如何使用 ActionCable 作为 API

Posted

技术标签:

【中文标题】如何使用 ActionCable 作为 API【英文标题】:How to use ActionCable as API 【发布时间】:2016-05-21 03:14:02 【问题描述】:

我使用 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) ->
    # ...

【问题讨论】:

【参考方案1】:

虽然 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 的开发人员很有用。至少在上面分享一个帖子。会有用的。【参考方案2】:

您基本上需要在您的其他应用程序 (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。为方便起见,我将在下面粘贴:

    连接到 Action Cable URL

    连接成功后,发送订阅消息

    订阅消息 JSON 应如下所示: "command":"subscribe","identifier":"\"channel\":\"MeshRelayChannel\"" 您应该会收到如下消息: "identifier"=>"\"channel\":\"MeshRelayChannel\"", "type"=>"confirm_subscription"

    订阅后,您可以发送消息。

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

    注意事项:

    发送到服务器的每条消息都有一个命令和标识符键。 通道值必须与 ActionCable 服务器上通道类的名称匹配。 identifierdata 被冗余 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。 用 ActionCable JS 的直接端口的链接更新了我的答案:github.com/mwalsher/actioncable-js。希望这会有所帮助! 非常非常好的解决方案。谢谢你把这个放在一起!这非常有帮助。我决定自己发布一个答案,因为我刚刚在 Rails 存储库中发现了一个带有官方 NPM 包的拉取请求。 例如,我想为此使用socket.io-client。如何使用socket.io-client 连接到MeshRelayChannel

以上是关于如何使用 ActionCable 作为 API的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ActionCable rails-5-api 应用程序中获取 current_user?

Rails API 应用程序中 ActionCable 的 Websocket 客户端

如何使用 RSpec 测试 ActionCable 频道?

如何在 minitest 中模拟和验证 ActionCable 传输?

如何在生产中使用 Nginx 和 Unicorn 配置 ActionCable?

ActionCable - 如何显示连接用户的数量?