嗨!各位朋友大家好,打給後,歹嘎吼,胎尬喉,我是阿圓,今天中秋收假,大家有從高速公路上下來了嗎?
廢話不多說,一樣有請今天的one piece:
(漢考克也是我蠻喜歡的一個角色!)
昨天我們說到 action cable 的基本操作,先幫各位複習一下:
今天繼續來說一些比較進階的設定:
每當有一次的 websocket 連線,連進server,就會有一個 connection 被創立(而 websocket 的 client 端,Rails 稱之為 consumer),connection,本身並不包含任何的身份驗證,也就是說,就算你沒有登入,你還是可以連接到 channel ,所以我們可以在 connction 建立時來驗證:
# 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 是使用:
def find_verified_user
if verified_user = env['warden'].user
verified_user
else
reject_unauthorized_connection
end
昨天提到了如何讓 server 正確廣播,也能讓 subscriber 正確收到訊息,而今天來提提不同型態的聊天室設定。
比較簡單的是大家都在同一個 channel 中,這樣就不用去管不同 stream 的部分。
若是不同 stream 的聊天室,你的 stream 可能要是某個params中的id,像是:
class RoomsChannel < ApplicationCable::Channel
def subscribed
room = Room.find(params[:room_id])
stream_for room
end
end
上面是依賴 room 這個 model 資料來建立 stream,而不同的 room 就有不同的 stream,如此一來,在js檔那邊也要一起做設定:
consumer.subscriptions.create({
channel: "RoomsChannel",
room_id: 1
},
...
等等等,這樣的設定是全部的人都進到了room_id: 1
的這個 stream 裡了,這樣不太對,我們會需要動態的去取得 room_id,你可以:
<div data-room-id="<%= @room.id %>">
...
</div>
這樣就可以找到對的連線,不過別忘了在js的部分加上,'turbolinks:load'
的監聽事件:
document.addEventListener('turbolinks:load', function () {
channel: "RoomChannel",
room_id: $('#room_messages).attr('data-room-id')
},
...
})
這樣就有辦法在不同的 room 裡面有不同的 stream 了!感謝各位看到這邊,若有任何建議,請各位不吝指教!我們明天見!