【问题标题】:How would you subscribe to specific stream using ActionCable您将如何使用 ActionCable 订阅特定流
【发布时间】:2020-10-12 22:48:51
【问题描述】:

我有一个原生 Rails Web 应用和一个带有聊天组件的 iOS 应用。我正在使用 ActionCable 提供实时消息传递。

在MessageController中创建消息时,服务器向MessageChannel中的两个流进行广播

  • 渲染的 html 去网络聊天
  • 要转到 iOS 应用程序的 json 对象

您可以创建特定于流的订阅吗?也就是在客户端,能不能从json广播中过滤掉html广播?

或者我应该创建一个 ApiMessageChannel 和一个 Web MessageChannel 吗?这感觉像是不必要的重复,因为 create 总是会同时向 web 和 api 广播。

消息频道

class MessageChannel < ApplicationCable::Channel
  def subscribed
    stop_all_streams
    stream_for Group.find(params["id"])
    stream_from "message:messages_api_#{params["id"]}"
  end
end

消息控制器

def create
# ... 

MessageChannel.broadcast_to group, message: render_to_string(message, locals: { previous_message: previous_message, type: group.type, current_user: current_user })

MessageChannel.broadcast_to "messages_api_#{group.id}", message: ApplicationController.render_with_signed_in_user(current_user, json: { sender: current_user.username, content: message.body })
end

聊天室控制器

import { Controller } from "stimulus"
import consumer from "channels/consumer"

export default class extends Controller {
  static targets = [ "messages", "newMessage" ]

  connect() {
    this.subscription = consumer.subscriptions.create({ channel: "MessageChannel", id: this.data.get("id") }, {
      connected: this._connected.bind(this),
      disconnected: this._disconnected.bind(this),
      received: this._received.bind(this)
    })
  }

  disconnect() {
    consumer.subscriptions.remove(this.subscription)
  }

  _connected() {
  }

  _disconnected() {
  }

  _received(data) {
    if (data.message) {
      this.messagesTarget.insertAdjacentHTML('beforeend', data.message);
      $('.js-chat-messages').scrollTop($('.js-chat-messages')[0].scrollHeight);
    }
  }

  clearMessage(event) {
    this.newMessageTarget.value = ''
  }
}

Swift iOS

static var ChannelIdentifier = "MessageChannel"
    let actionCableClient = ActionCableClient(url: URL(string: "wss://localhost:3000/cable")!)

        actionCableClient.headers = [
            "Authorization": token,
            "Accept": "application/json"
        ]
        
        actionCableClient.connect()

        let room_identifier = ["id" : "12"]
        actionCableChannel = actionCableClient.create(ActionCableController.ChannelIdentifier, parameters: room_identifier, autoSubscribe: true, bufferActions: true )

actionCableChannel?.onReceive = { (data: Any?, error: Error?) in
            print("recieved message!")
            if let error = error {
                print("ERROR: Unable to receive message from ActionCable Channel: \(error.localizedDescription)")
                return
            }
    ```

【问题讨论】:

    标签: ios ruby-on-rails swift actioncable


    【解决方案1】:

    要订阅特定的命名流,您可以:

    class MessageChannel < ApplicationCable::Channel
      def subscribed
        # stream_from "message:messages_web"
        # stream_from "message:messages_api"
        # stream_from "message:messages_test"
    
        stream_from "message:messages_#{params[:type]}"
    
        # !! can also add in other parameters and add those on the client side for stream specific filtering
        # stream_from "message:messages_#{params[:type]}_#{params[:id]}"
    
      end
    end
    
    class MessagesController < ApplicationController
      def create
        MessageChannel.broadcast_to "messages_web", 'web'
        MessageChannel.broadcast_to "messages_api", 'api'
        MessageChannel.broadcast_to "messages_test", 'test'
      end
    end
    
    import consumer from "channels/consumer"
    this.subscription = consumer.subscriptions.create({ channel: "MessageChannel", type: 'web'}, {
      connected: this._connected.bind(this),
      disconnected: this._disconnected.bind(this),
      received: this._received.bind(this)
    })
    

    这只会接收来自“message:messages_web”的消息

    【讨论】:

      【解决方案2】:

      根据文档,你可以知道如下:

      发现订阅的方法是通过客户端javascript调用的,而不是由rails控制器调用的。

      根据你的问题,你应该订阅特殊资源吧?

      【讨论】:

      • 特殊资源是什么意思?有没有办法在客户端过滤流?有没有办法在不创建 2 个单独频道的情况下进行订阅?
      猜你喜欢
      • 2015-06-24
      • 2019-03-19
      • 2020-12-12
      • 2017-04-07
      • 2018-06-14
      • 1970-01-01
      • 2017-03-28
      • 2017-12-19
      • 2011-04-18
      相关资源
      最近更新 更多