WebSockets:可以连接但不能订阅频道

时间:2019-03-15 15:28:56

标签: ruby-on-rails nginx redis flutter actioncable

我在nginx中与乘客一起运行了仅Rails API的应用程序。我正在尝试使用Action Cable在Flutter中建立一个简单的聊天应用程序,但似乎无法使其正常工作。

我可以使用以下方法进行连接:

 channel = IOWebSocketChannel.connect("wss://my.domain/cable")

并在发生这种情况时在我的production.log中查看以下内容:

Started GET "/cable" for [redacted] at 2019-03-14 19:44:09 +0000
Started GET "/cable" [WebSocket] for [redacted] at 2019-03-14 19:44:09 +0000
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: upgrade, HTTP_UPGRADE: websocket)
Doorkeeper::AccessToken Load (0.3ms)  SELECT  `oauth_access_tokens`.* FROM `oauth_access_tokens` WHERE `oauth_access_tokens`.`token` = '[redacted]' LIMIT 1
User Load (0.2ms)  SELECT  `users`.* FROM `users` WHERE `users`.`id` = 2 LIMIT 1
Registered connection (Z2lkOi8vYWdlbnQyNHg3L1VzZXIvMg)

因此连接似乎已建立并成功升级

然后我要发送订阅命令

channel.sink.add(json.encode({
  "command": "subscribe",
  "identifier": {"channel": "ConversationChannel", "conversation_id": "${conversation.id}"}
}));

我不确定执行此命令后是否应该在日志文件中看到任何内容,但我没有。没有任何反应,也没有任何迹象表明我的production.log或nginx错误日志中有任何错误。我在ConversationChannel的subscription方法中设置了一些日志,以便它至少在调用时会向生产日志中输出一些内容,这样我就可以测试它是否至少在调用subscribe命令

class ConversationChannel < ApplicationCable::Channel
    def subscribed
      Rails.logger.info "test conversation subscribe"
      reject && return unless current_user
      stream_from "conversation_#{params[:conversation_id]}_channel"
    end

    ...

end

但是它没有出现在production.log中,因此订阅命令似乎没有到达应该去的地方。

然后我尝试使用here中位于a conversation on github regarding connection states的代码使用dart WebSocket,以查看是否可以确定连接是否恢复正常。

在我的域中运行该代码时,我在production.log中看到相同的成功连接,但是该连接实际上以onerror TimeoutException after 0:00:15.000000: Future not completed超时,这似乎表明该连接实际上没有< / em>毕竟成功了,尽管它在日志文件中说了什么。

我在这里做什么错了?

1 个答案:

答案 0 :(得分:0)

如果我记得,当您尝试连接到频道时,您的标识符必须是JSON字符串化的,以及整个JSON对象。看一下此链接:

https://thoughtbot.com/blog/talking-to-actioncable-without-rails

尤其是:

const msg = {
  command: 'subscribe',
  identifier: JSON.stringify({
    channel: 'SomeChannel',
  }),
};
socket.send(JSON.stringify(msg));

Rails在后端执行整个JSON解析。看看这是否对您有帮助。尝试连接WebSocket时,在没有使用其ActionCable npm库的情况下,我遇到过类似的问题。