没有收到广播

时间:2016-11-22 18:58:45

标签: ruby-on-rails websocket actioncable

我使用Rails5为我的应用程序创建api提供程序,并且,我需要使用websocket。

然后,我创建了一个非常简单的测试代码:

的routes.rb

Rails.application.routes.draw do

  mount ActionCable.server => '/cable'

  get '/testbroad', to: 'messages#testbroad'

end

messages_channel.rb

class MessagesChannel < ApplicationCable::Channel

  def subscribed
    stream_from 'messages'
  end

end

messages_controller.rb

class MessagesController < ApplicationController

  def testbroad
    ActionCable.server.broadcast('messages',
                                 message: 'foo')
    head :ok
  end

end

然后,我使用cURL

开始连接
➜  ~ curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" -H "Host: ws://localhost:3000/cable" http://localhost:3000/cable
HTTP/1.1 101 Web Socket Protocol Handshake
Upgrade: WebSocket
Connection: Upgrade
WebSocket-Location: ws://ws://localhost:3000/cable/cable

{"type":"welcome"}

它的工作!但是,当我尝试发送广播时......

➜  ~ curl http://localhost:3000/testbroad

The Rails&#39;控制台显示成功,但是,我没有在cURL中收到任何消息。为什么我没有收到消息&#34; foo&#34;?如何解决?

2 个答案:

答案 0 :(得分:1)

几个小时后,我发现了问题。

此图像是启动WebSocket连接的页面中的网络调试。 enter image description here 该表的第一行显示了浏览器发送给服务器的消息{"command":"subscribe","identifier":"{\"channel\":\"MessagesChannel\"}"}

建立连接后,我需要发送一条包含我想要订阅的频道的消息。它不是写在Rails的文档中。

答案 1 :(得分:1)

我也想更好地理解这一点,所以基本上你订阅但是你没有发布任何消息。他们在这里的关键是执行messages#testbroad

ActionCable.server.broadcast('messages',
                             message: 'foo')
head :ok

订阅在文件app/channels/messages_channel.rb

中设置

我引用documentation

  

3.2.2订阅

     

消费者订阅频道,充当订阅者。他们的连接称为订阅。然后,根据有线电视消费者发送的标识符,将生成的消息路由到这些频道订阅。

def subscribed
    stream_from 'messages'
end 

我相信它能够理解订阅该频道的消费者

  

基于有线消费者发送的标识符

(有线消费者是从redis db读取的消费者)。通过这种方式,它可以了解想要接收通知的用户以及不再订阅活动频道的用户,app/assets/javascripts/channels/messages.js将触发App.cable.subscriptions.create('MessagesChannel')在客户端前端发布消息。

App.cable.subscriptions.create('MessagesChannel', {      
  received: function(data) {
      $('#messages').append(this.renderMessage(data));
  },
  renderMessage: function(data) {
      return "<br><p> <strong>" + data.user + ": </strong>" + data.message + "</p>";
  }
});

我发布的答案是讨论 ActionCable 并获得更好的理解。我知道你已经解决了这个问题。但我想讨论一下这个问题。

我还不清楚!