21

我使用 Rails 5 beta 1 和 ActionCable 构建了一个非常简单的应用程序来显示用户何时上线并让他们互相发送消息。

现在,我基本上想采用 ActionCable 的客户端部分,在另一个应用程序(不在Rails 5 上运行)的上下文中实现它,并将它与第一个应用程序连接以发送和接收数据(例如在线用户或消息的状态)。

我假设要从第二个应用程序发送数据,我可以简单地发出 AJAX POST 请求。问题是:如何从我的第二个应用订阅第一个应用的开放连接?

甚至:如何通过 API 从另一个应用程序订阅我的 Rails 应用程序的 ActionCable 连接?

我的猜测是,我基本上想在我的第二个应用程序中以某种方式包含这个咖啡脚本:

App.appearance = App.cable.subscriptions.create "AppearanceChannel",
  connected: ->
    # Called when the subscription is ready for use on the server

  disconnected: ->
    # Called when the subscription has been terminated by the server

  received: (data) ->
    # ...
4

2 回答 2

23

虽然 mwalsher 的解决方案对我非常有帮助,但我最近在 Rails 存储库上发现了一个拉取请求,其中包含我的问题的官方解决方案。

https://github.com/rails/rails/pull/24991

我认为,在不久的将来,这将被添加到主文档中。这是官方 actioncable npm 包的链接:https ://www.npmjs.com/package/actioncable

您可以将它与任何 JS 应用程序一起使用,类似于 mwalsher 的解决方案。只需安装 npm 包:

npm install actioncable --save

这里是文档中的 JS 示例:

ActionCable = require('actioncable')

var cable = ActionCable.createConsumer('wss://RAILS-API-PATH.com/cable')

cable.subscriptions.create('AppearanceChannel', {
  // normal channel code goes here...
});

编辑:拉取请求已经合并了一段时间,现在描述是官方自述文件的一部分——只是还没有在 Rails 指南中。

于 2016-06-28T07:34:48.230 回答
20

您基本上需要在您的其他应用程序 ( https://github.com/rails/rails/tree/master/actioncable/app/assets/javascripts ) 中包含 ActionCable JS 代码的副本或端口。

更新:我最近发布了一个名为 actioncable-js 的 npm 包,它提供了 Ruby on Rails 5 的 ActionCable CofeeScript 到标准 JS 的直接端口,以便在 Rails 之外使用:https ://github.com/mwalsher/actioncable-js

因为 ActionCable 只是 HTML5 WebSockets 之上的一层,所以您也可以使用原始 WebSockets JS 代码(或任何第三方库)来处理消息传递。

ActionCable 消息协议在此处有所记录:https ://github.com/NullVoxPopuli/action_cable_client#the-action-cable-protocol 。为方便起见,我将粘贴在下面:

  1. 连接到 Action Cable URL
  2. 连接成功后,发送订阅消息

    • 订阅消息 JSON 应如下所示: {"command":"subscribe","identifier":"{\"channel\":\"MeshRelayChannel\"}"}
    • 您应该会收到这样的消息: {"identifier"=>"{\"channel\":\"MeshRelayChannel\"}", "type"=>"confirm_subscription"}
  3. 订阅后,您可以发送消息。

    • 确保操作字符串与 ActionCable 服务器上的数据处理方法名称匹配。
    • 您的消息 JSON 应如下所示: {"command":"message","identifier":"{\"channel\":\"MeshRelayChannel\"}","data":"{\"to\":\"user1\",\"message\":\"hello from user2\",\"action\":\"chat\"}"}
    • 收到的消息应该看起来差不多
  4. 笔记:

    • 发送到服务器的每条消息都有一个命令和标识符键。
    • 通道值必须与 ActionCable 服务器上的通道类名称相匹配。
    • identifier并且data被冗余地 jsonified。

所以,例如(在红宝石中)

payload = {
  command: 'command text',
  identifier: { channel: 'MeshRelayChannel' }.to_json,
  data: { to: 'user', message: 'hi', action: 'chat' }.to_json
}.to_json
于 2016-03-20T22:52:44.837 回答