【问题标题】:rails 5 - Create channel per conversation by ActionCablerails 5 - 通过 ActionCable 为每个对话创建频道
【发布时间】:2016-07-14 23:34:17
【问题描述】:

我是一名新的 Rails 开发人员,并开始使用 Rails 5 中的 ActionCable 创建聊天应用程序。

问题是互联网上有很多使用 ActionCable 的聊天示例,但都非常简单。他们创建了一个频道,所有连接到该频道的用户都可以发送或阅读其他人的消息。

例如,他们创建了一个这样的聊天频道:

class ChatChannel < ApplicationCable::Channel
  def subscribed
    stream_from 'messages'
  end

  def speak(data)
    ActionCable.server.broadcast('messages',
      message: render_message(data['message']))
  end

  private

  def render_message(message)
    ApplicationController.render(partial: 'messages/message',
                                 locals: { message: message })
  end
end

在客户端,它们连接到该通道

App.chat = App.cable.subscriptions.create "ChatChannel",
  received: (data) ->
    $('#messages').append(data.message)

  speak: (msg) ->
    @perform 'speak', message: msg

如何为 2 个用户之间的每个对话创建一个频道?

【问题讨论】:

    标签: ruby-on-rails websocket chat actioncable


    【解决方案1】:

    唯一改变的是您订阅的频道。在这种情况下应该是一个特定的对话。你可以有这样的东西:

    messages.coffee

    $(document).on "turbolinks:load", ->
      messages = $("#messages-list")
    
      App.Messages = App.cable.subscriptions.create {
        channel: "MessagesChannel"
        # You can grab the conversation id as a data attribute from the messages container of your conversation and pass it as a parameter to the channel
        conversation_id: messages.data("conversation-id")
      },
    
      connected: ->
    
      disconnected: ->
        # Called when the subscription has been terminated by the server
    
      received: (data) ->
        messages.append(data["message"])
        $("#new_message")[0].reset();
    

    messages_channel.rb

    class MessagesChannel < ApplicationCable::Channel
      def subscribed
        stream_from "conversation_#{params['conversation_id']}_channel"
      end
    
      def unsubscribed
        # Any cleanup needed when channel is unsubscribed
      end
    end
    

    messages_controller.rb

    # You can have something like this in your create action
    def create
        message = @conversation.messages.build(message_params)
        message.user = current_user
        message.save
    
        ActionCable.server.broadcast "conversation_#{message.conversation.id}_channel",
          message: render_message(message)
    
        head :ok
    end
    
    private
    
      def set_conversation
        @conversation = Conversation.find(params[:conversation_id])
      end
    
      def render_message(message)
        render partial: "messages/message", locals: { message: message }
      end
    

    【讨论】:

    • 谢谢。这绝对是我已经用来处理该问题的一种方法
    • 很高兴它有帮助!如果这是您需要的,请将其标记为已接受。
    • 如果您的网址中没有conversation_id,我认为这不会起作用。你介意建议你这样做吗?我目前正在处理此问题,但对话显示在列出所有对话的索引页面上。想想 messenger.com
    • 你有什么理由设置MessagesChannel但从conversation_channel流式传输?
    猜你喜欢
    • 2023-03-27
    • 1970-01-01
    • 2018-06-19
    • 2021-08-22
    • 2017-12-12
    • 2016-06-05
    • 2017-01-04
    • 2016-11-05
    • 1970-01-01
    相关资源
    最近更新 更多