iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 27
0
自我挑戰組

Ruby on Rails 新手的30個問題!系列 第 27

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 建立時來驗證:

# 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

不同 stream 的聊天室

昨天提到了如何讓 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,你可以:

  1. 從 url 裡抓
  2. 寫在 html.erb 裡
<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 了!感謝各位看到這邊,若有任何建議,請各位不吝指教!我們明天見!


上一篇
Day_26 action cable ?(3)
下一篇
Day_28 專案部署?Heroku ?
系列文
Ruby on Rails 新手的30個問題!30

尚未有邦友留言

立即登入留言