代码之家  ›  专栏  ›  技术社区  ›  Leo Le

rails 5-通过ActionCable创建每次对话的频道

  •  3
  • Leo Le  · 技术社区  · 10 年前

    我是一名新的Rails开发人员,开始在Rails5中使用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
    

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

    1 回复  |  直到 10 年前
        1
  •  8
  •   Andrés Da Viá    10 年前

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

    消息.咖啡

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

    消息_频道.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
    

    消息_控制器.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