iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 26
0
自我挑戰組

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

Day_26 action cable ?(3)

嗨!各位朋友大家好,烤肉節快樂,我是阿圓,一樣有請今天的one piece:

(烤肉慶典持續中!)

昨天我們說完了 Pub/Sub 模式,今天來說說 Rails 中的 action cable。

action cable 基本介紹

再來複習一下昨天的圖:

publisher 發送出去的訊息,透過代理層(message broker)的方式將訊息廣播給 subscriber

而 Rails 中,代理層的部分是 channel,可以透過產生器,來產生channel
rails g channel xxx
xxx 可以換成想取的名字 (例如,親親小可愛之類的),會建立出下面這些檔案:

Running via Spring preloader in process 27571
      invoke  test_unit
      create  test/channels/xxx_channel_test.rb
      create  app/channels/xxx_channel.rb
   identical  app/javascript/channels/index.js
   identical  app/javascript/channels/consumer.js
      create  app/javascript/channels/xxx_channel.js

先來看 app/channels/xxx_channel.rb,這裡面是定義當 subscriber,訂閱,或是取消訂閱 channel時的事情。

class XxxChannel < ApplicationCable::Channel
# 會有一個最上層的 channel,底下有很多的小 channel。
  def subscribed
    stream_from "qqq_stream"
  end

  def unsubscribed
    # Any cleanup needed when channel is unsubscribed
  end
end

channel 透過 stream 來廣播訊息,常用的有以下方法:
stop_all_streams() :取消所有stream。
stream_from "xxx_channel" :透過名為xxx_channel的stream 來廣播。
stream_for (model) :可以透過以建立的 model,產生 stream 來廣播。


app/javascript/channels/xxx_channel.js,則是定義了 client 端的行為,分別有:

import consumer from "./consumer"
consumer.subscriptions.create("XxxChannel", {
  connected() {
    //連線,變成 subscriber
    // Called when the subscription is ready for use on the server
  },

  disconnected() {
    // 斷線
    // Called when the subscription has been terminated by the server
  },

  received(data) {
    // 接收資料
    // Called when there's incoming data on the websocket for this channel
  }
});

其中 consumer.subscriptions.create("XxxChannel",{...}),這裡的意思是將 consumer 連上 XxxChannel,當 channel 那邊透過 stream(上面定義的名稱是'qqq_stream') 廣播出訊息,就會藉由 received 的 function 接收到資料。

這樣已經將簡單的連線做好了,但若要實際看到效果,還需要做一點設置:

# /cable.yml
development:
  adapter: async
  #把這邊改成 redis

test:
  adapter: test

production:
  adapter: redis
  url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
  channel_prefix: Test_production

(redis 是一種無關聯性、 key-value 型的資料庫,一般會搭配關聯性資料庫,作為快取用,其他詳細介紹,請參考 wiki)

最後就可以去 rails console 裡面:

ActionCable.server.broadcast "qqq_channel", {message:"Hello world!"}
# 請記得,channel 是透過 stream 來廣播訊息!

這樣身為XxxChannelqqq_stream的訂閱者,都可以收到這條訊息,並且在瀏覽器的 console 裡顯示出來。

(若廣播成功會回傳1)

以上就是今天的 action cable 基本介紹,明天我們再來進階一些,感謝各位看到這邊,若有任何建議,請各位不吝指教!我們明天見!


參考文章

官方文件
官方手冊
還有夥伴大方分享的筆記!


上一篇
Day_25 action cable? (2) Web Socket ?
下一篇
Day_27 action cable ? (4)
系列文
Ruby on Rails 新手的30個問題!30

尚未有邦友留言

立即登入留言