如何将 ActionCable 用作 API

23
我用Rails 5 beta 1和ActionCable建立了一个非常简单的应用程序,以显示用户何时在线,并让他们互发消息。
现在,我基本上想把ActionCable的客户端部分实现到另一个不运行在Rails 5上的应用程序中,并将其与第一个应用程序连接起来以发送和接收数据(例如用户的在线状态或消息)。
为了从第二个应用程序发送数据,我认为可以简单地进行AJAX POST请求。问题是:如何从我的第二个应用程序订阅到第一个应用程序的开放连接?
甚至可以问:如何通过API从另一个应用程序订阅到我的Rails应用程序的ActionCable连接?
我猜测,我基本上想在我的第二个应用程序中以某种方式包含这个coffeescript代码:
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) ->
    # ...
2个回答

23

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

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

由于 ActionCable 只是 HTML5 WebSocket 上的一层,因此您也可以使用原始 WebSocket 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 服务器上的通道类名称匹配。
    •     
    • 标识符和数据是冗余地进行 JSON 化的。

因此,例如(在 ruby 中)

payload = {
  command: 'command text',
  identifier: { channel: 'MeshRelayChannel' }.to_json,
  data: { to: 'user', message: 'hi', action: 'chat' }.to_json
}.to_json

是的,我也在研究这个。但我感觉它并不是那么简单明了,至少对我来说不是。有些部分需要进行调整,不能简单地复制粘贴。 不幸的是,ES6版本似乎无法与最新版本的Rails 5兼容。 - sam
我更新了我的答案,并附上了一个直接移植的ActionCable JS链接:https://github.com/mwalsher/actioncable-js。希望这对你有所帮助! - mwalsher
真的非常好的解决方案。感谢您的付出!这非常有帮助。我决定在我们自己的答案中发布一个答案,因为我刚刚在Rails repo上找到了一个官方的NPM包的pull request。 - sam
例如,我想使用socket.io-client来实现。我如何使用socket.io-client连接到MeshRelayChannel - sreang rathanak

23

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

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

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

您可以像mwalsher的解决方案一样,使用它与任何JS应用程序。只需安装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...
});

编辑:该拉取请求已经合并了一段时间,现在描述已经成为官方Readme的一部分 - 只是还没有出现在Rails指南中。


@jim broski 请分享这两个应用程序的开放库,这对于新接触Rails和ActionCable的开发人员非常有帮助。至少发布一篇文章来分享它,这将非常有用。 - Modi Ranga Nayakulu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接