【问题标题】:Running websockets server side client in parallel to backend app with rails faye websockets使用 rails faye websockets 与后端应用程序并行运行 websockets 服务器端客户端
【发布时间】:2021-12-15 23:17:28
【问题描述】:

我正在尝试设置服务器端 websocket 客户端,以便能够使用来自现有 3rd 方 websockets 服务的消息。

我需要能够:

  • 继续运行现有应用,主要由后端 api 服务组成
  • 使用来自第 3 方 websocket 服务器的消息
  • 在现有 sidekiq 工作人员中使用这些消息中的数据

我使用了来自faye web sockets 的客户端配置,并遵循了heroku/websockets 示例here,无论是否在app.rb 中使用中间件配置。我可以连接到 websocket 并毫无问题地接收消息,但这似乎锁定了其他所有内容,并且在部署到 heroku 时应用程序崩溃了。

当在 app.rb 中配置为中间件时,错误是: Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch

如果没有在那里配置,应用程序甚至不会尝试启动,因为 EM 会接管。

我最终将 EM 代码从上面的一个 Sidekiq 工作程序内部的 faye web sockets 链接中移动,这成功了。但这会奏效吗? sidekiq 工作人员可以无限期运行还是最终会被终止?我找不到任何严格使用服务器端客户端的示例,因此我不知道这种解决方法是否可持续。

对解决此问题的最佳方法有什么想法吗?

【问题讨论】:

    标签: ruby-on-rails ruby websocket sidekiq faye


    【解决方案1】:

    但这似乎锁定了其他所有内容,并且在部署到 heroku 时应用程序崩溃了。

    显然,WebSocket 客户端将使用一个线程(或主线程),永久阻塞它,无限期地阻止应用程序的其余部分运行。

    我最终将 EM 代码从上面的 Sidekiq 工作人员内部的 faye web sockets 链接中移动,这成功了

    之所以可行,是因为 Sidekiq 和 Rails 将在不同的进程/dynos 上运行,但它绝对不是最干净的方式,而且 Sidekiq 不适合这种长生命周期的进程,如 Web 服务器。


    您不应将长时间运行的进程用作中间件。中间件应该只委托给链中的下一个。虽然有一些方法可以实现这一点,比如在一个新线程上运行你的服务器(甚至可能由于 GIL 而失败),但最好的办法是完全使用不同的进程来运行可以访问 Rails 上下文的 websocket 客户端。

    您的 procfile 可能如下所示:

    web: rails s -p $PORT -e production
    websocket: rails runner web_socket_server.rb # or other command
    sidekiq: bundle exec sidekiq # etc
    

    这样您的客户端就在parallel 中运行,而不是concurrently(现在就是这样)。

    如果你仍然想使用中间件(我强烈反对),只需运行两个不同的 Rails 进程,一个有中间件,一个没有。

    【讨论】:

    • 太棒了。我会试一试。我最大的问题是,如果套接字位于另一个 ruby​​ 文件中,我无法找到如何运行它,但这应该可以。类似地,作为单个 EM 进程的一部分运行多个套接字是否存在问题?这些应该分开吗?
    • 我对 EM 的了解非常少,对 Faye 插座的了解也更少。也许您可以查看 EM 文档以了解如何使用 EM.run 或其他合适的方法安全地运行并发进程。您需要注意的是阻止 EM 从一个任务切换到下一个任务的阻塞操作,并确保您没有使用多个线程,因为 EM 是单线程的并且会阻塞所有其他线程。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-29
    • 2017-05-19
    • 1970-01-01
    • 2016-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多