rails 5 - 通过ActionCable为每个对话创建频道



我是一个新的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 个用户之间的每个对话中创建一个频道?

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

消息.咖啡

$(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

最新更新