Rails 5 - ActionCable - 无法升级到 WebSocket

Posted

技术标签:

【中文标题】Rails 5 - ActionCable - 无法升级到 WebSocket【英文标题】:Rails 5 - ActionCable - Failed to upgrade to WebSocket 【发布时间】:2017-03-13 17:30:09 【问题描述】:

我正在尝试在我的 Rails 5 应用程序上实现 webSocket。

这是我的频道:

class MessagesChannel < ApplicationCable::Channel
  def subscribed
    stream_from "messages_#params[:topic]"
  end
end

在我的控制器中我这样做:

    ActionCable.server.broadcast "messages_#params[:topic_id]",
      message: @message.message,
      user: current_user.name

还有我的连接类(也使用设备):

module ApplicationCable
  class Connection < ActionCable::Connection::Base
    identified_by :current_user

    def connect
      self.current_user = find_verified_user
      logger.add_tags 'ActionCable', current_user.email
    end

    protected

    def find_verified_user # this checks whether a user is authenticated with devise
      if verified_user = env['warden'].user
        verified_user
      else
        reject_unauthorized_connection
      end
    end
  end
end

客户端是一个Nodejs应用,只是为了测试:

module.exports.webSocket = function(topic)
  const WebSocket = require('ws');

  const ws = new WebSocket('ws://localhost:3000/cable');

  ws.on('open', function open() 
    console.log("on open!!");
  );

  ws.on('message', function incoming(data, flags) 
    console.log("got here!");
    console.log(data);
    console.log(flags);
    // flags.binary will be set if a binary data is received.
    // flags.masked will be set if the data was masked.
  );
;

这就是我得到的:

Started GET "/cable" for 127.0.0.1 at 2017-03-13 14:25:01 -0300
Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2017-03-13 14:25:01 -0300
Request origin not allowed:
Failed to upgrade to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
Finished "/cable/" [WebSocket] for 127.0.0.1 at 2017-03-13 14:25:01 -0300

我也不知道如何在 NodeJS 客户端上指定要收听的频道。这也很有帮助

EDIT 1 - 尝试将以下内容添加到 development.rb

config.action_cable.allowed_request_origins = ['http://localhost:3000']

EDIT 2 - 还尝试在节点客户端上添加通道,如下所示:

const ws = new WebSocket('ws://localhost:3000/cable', `messages_$topic`);

但是两次尝试都没有成功。

EDIT 3 - 另一个客户端测试:

  ws.on('open', function open() 
    console.log("on open!!");
     ws.send('"command":"subscribe","identifier":"\"channel\":\"MessagesChannel\""');
  );

【问题讨论】:

【参考方案1】:

您的客户端在哪个端口上运行?您想允许客户端,因此如果 rails 在 localhost 3000 上运行,您需要将其更改为正确的原始 url:

config.action_cable.allowed_request_origins = ['http://localhost:3000']

为了发展,我暂时只使用正则表达式来允许所有来源:

config.action_cable.allowed_request_origins = [ /http:\/\/.*/, /https:\/\/.*/ ]

为了更轻松地测试连接,请使用这个 jsfiddle - 现在无需设置您的客户端,只是为了能够连接:

http://jsfiddle.net/BrilliantLa8s/bxkerzf8/2/

连接后,我建议您使用此库从您的客户端订阅动作有线电视频道,因为您提到了 Node,我假设该库将用 javascript 编写

https://www.npmjs.com/package/actioncable-js

【讨论】:

多么棒的答案!所以我已经测试过了。我已连接。有用。但是有一个问题。我正在使用 nodejs 来测试它。但是我会有另一个使用 react-native 的客户端(它使用 WebSockets)。那么我怎样才能“订阅”一个只使用 websockets 的频道呢?或者我必须使用另一个库来实现这一点? 另一个说明:github.com/mwalsher/actioncable-js/blob/master/dist/… 使用 document 。而且我的节点应用程序不在浏览器上运行。 :(

以上是关于Rails 5 - ActionCable - 无法升级到 WebSocket的主要内容,如果未能解决你的问题,请参考以下文章

在 Heroku 上部署 ActionCable (Rails 5 beta4)

Rails 5.1 - ActionCable没有更新?

ActionCable Rails 5 (Passenger) - 失败:WebSocket 握手期间出错:意外响应代码:404

使用 AWS Elastic Beanstalk 部署 Rails ActionCable

Rails 4 和 ActionCable

在 Rails 中的控制台无法使用 Actioncable 广播