--- title: 12th 鐵人賽 Day_27 action cable ? (4) tags: 12th 鐵人賽 --- # 12th 鐵人賽 Day_27 action cable ? (4) 嗨!各位朋友大家好,打給後,歹嘎吼,胎尬喉,我是阿圓,一樣有請今天的one piece:  (漢考克也是我蠻喜歡的一個角色!) 昨天我們說到 action cable 的基本操作,先幫各位複習一下: 1. action cable 採用 pub/sub (發布/訂閱) 的模式 2. 每一個 client 端,透過訂閱 channel 成為 subscriber 3. server 透過 channel 中的 stream 將訊息廣播(Broadcast)出去 今天繼續來說一些比較進階的設定: # connection 每當有一次的 websocket 連線,連進server,就會有一個 connection 被創立(而 websocket 的 client 端,Rails 稱之為 consumer),connection,本身並不包含任何的身份驗證,也就是說,就算你沒有登入,你還是可以連接到 channel ,所以我們可以在 connction 建立時來驗證: ```ruby= # app/channels/application_cable/connection.rb module ApplicationCable class Connection < ActionCable::Connection::Base identified_by :current_user def connect self.current_user = find_verified_user end private def find_verified_user if verified_user = User.find_by(id: cookies.encrypted[:user_id]) verified_user else reject_unauthorized_connection end end end end ``` 上述是利用 cookie 的方式去驗證,若自己有訂定義驗證使用者的方式可以拿來用,像 devise 是使用: ```ruby= def find_verified_user if verified_user = env['warden'].user verified_user else reject_unauthorized_connection end ``` ## 一對一的聊天室 昨天提到了如何讓 server 正確廣播,也能讓 subscriber 正確收到訊息,而今天來提提不同型態的聊天室設定。 比較簡單的是一對多的聊天室,也就是大家都在同一個 channel 中,這樣就不用去管不同 stream 的部分。 若是一對一的聊天室,你的stream可能要是某個params中的id,像是: ```ruby= class RoomsChannel < ApplicationCable::Channel def subscribed room = Room.find(params[:room_id]) stream_for room end end ``` 上面是依賴 room 這個 model 資料來建立 stream,而不同的 room 就有不同的 stream ,這樣能夠達到一對一的方式 這樣的話,在js檔那邊也要一起做設定: ```javascript= consumer.subscriptions.create({ channel: "RoomsChannel", room_id: 1 }, ... ``` 等等等,這樣的設定是全部的人都進到了`room_id: 1`的這個 stream,這樣不太對,我們會需要動態的去取得 room_id,你可以: 1. 從 url 裡抓 2. 寫在 html.erb 裡 ```htmlmixed= <div data-room-id="<%= @room.id %>"> ... </div> ``` 這樣就可以找到對的連線,不過別忘了在js的部分加上,`'turbolinks:load'`的監聽事件: ```javascript= document.addEventListener('turbolinks:load', function () { channel: "RoomChannel", room_id: $('#room_messages).attr('data-room-id') }, ... }) ``` 這樣就有辦法在不同的 room 裡面有不同的 stream 了!感謝各位看到這邊,若有任何建議,請各位不吝指教!我們明天見! 
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up