Javascript 当我在Unicorn服务器上运行时,WebSocket在我的Rails应用程序中不工作,但在瘦服务器上工作

Javascript 当我在Unicorn服务器上运行时,WebSocket在我的Rails应用程序中不工作,但在瘦服务器上工作,javascript,ruby-on-rails,heroku,websocket,Javascript,Ruby On Rails,Heroku,Websocket,我正在学习RubyonRails在Heroku上使用websocket构建一个实时web应用程序,但我不明白为什么在Unicorn服务器上运行时websocket连接会失败。我将我的Rails应用程序配置为在本地和Heroku上运行,使用Procfile web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb …我在本地以$foreman start开始。使用javascript在客户端上创建websocket连接时出错 var dis

我正在学习RubyonRails在Heroku上使用websocket构建一个实时web应用程序,但我不明白为什么在Unicorn服务器上运行时websocket连接会失败。我将我的Rails应用程序配置为在本地和Heroku上运行,使用Procfile

web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb
…我在本地以
$foreman start
开始。使用javascript在客户端上创建websocket连接时出错

var dispatcher = new WebSocketRails('0.0.0.0:3000/websocket'); //I update the URL before pushing to Heroku
…由于Chrome Javascript控制台中出现以下错误,
“到ws://0.0.0.0:3000/websocket的websocket连接”失败。在收到握手响应之前,连接已关闭。

…当我在Heroku上的Unicorn上运行它时,我在Chrome Javascript控制台中得到一个类似的错误,
'websocket连接到ws://myapp.herokuapp.com/websocket'失败。websocket握手时出错。意外响应代码:500。

Heroku日志中的堆栈跟踪显示,
RuntimeError(eventmachine未初始化:evma\u install\u oneshot\u timer):

奇怪的是,当我使用命令
$rails s
在瘦服务器上本地运行它时,它工作正常


我花了五个小时在网上研究这个问题,还没有找到解决办法。如果您有任何关于修复此问题的想法,甚至是从我的工具中获取更多信息的想法,我们将不胜感激

更新:我发现很奇怪,websocket rails只支持基于EventMachine的web服务器,而websocket rails所基于的web服务器支持

经过进一步的调查和测试,我意识到我先前的假设是错误的。websocket rails似乎不需要基于EventMachine的web服务器,而是需要支持
rack.jack
的多线程web服务器(因此没有Unicorn)。(成为独角兽时满足此标准。)

基于此假设,我尝试使用最直接的方法解决
EventMachine not initialized
错误,即初始化EventMachine,方法是将以下代码插入初始化器
config/initializers/EventMachine.rb

Thread.new { EventMachine.run } unless EventMachine.reactor_running? && EventMachine.reactor_thread.alive?
还有<坚强>成功

我已经能够让Websocket Rails通过一个端口在本地服务器上运行,使用而不使用。(ruby 2.1.3p242上的Rails 4.1.6)

这应该适用于Heroku,只要您在web服务器选择方面没有限制

警告:这不是官方支持的websocket rails配置。使用多线程web服务器(如Puma)时必须小心,因为您的代码及其依赖项必须是线程安全的。A(临时?)是将每个工作线程的最大线程数限制为一个,并增加工作线程数,从而实现类似于Unicorn的系统


出于好奇,在解决了上述问题后,我再次尝试了独角兽:

  • web服务器接收到第一个websocket连接(
    Started GET”/websocket)for…
    ),但是 websocket客户端的
    状态
    被卡在
    连接上
    ,似乎挂起 无限期

  • 第二次连接导致HTTP错误代码500以及
    app
    错误:死锁;递归锁定(ThreadError)
    显示在 服务器控制台输出

通过移除
Rack::Lock
的(潜在危险)操作,可以解决死锁错误,但连接仍然挂起,即使服务器控制台显示连接已被接受

毫不奇怪,这失败了。从错误消息中,我认为Unicorn是不兼容的,原因与它的网络架构(线程/并发)有关。但话说回来,这可能只是这个特定机架中间件中的一些错误

有人知道独角兽不兼容的具体技术原因吗


原始答案:

您是否检查了web服务器和WebSocket服务器的端口及其调试日志?这些错误消息听起来像是连接到WebSocket服务器以外的其他服务器

您使用的两个web服务器的一个关键区别似乎是一个(瘦)基于EventMachine,另一个(Unicorn)不基于EventMachine。Websocket Rails项目wiki声明,必须将a用于基于非EventMachine的web服务器,例如Unicorn(这需要在Heroku上进行更复杂的设置,因为它需要Redis服务器)。错误消息
RuntimeError(EventMachine未初始化:evma\u install\u oneshot\u timer):
表明未使用独立模式


Heroku AFAIK仅作为端口80对外公开(作为环境变量提供)。WebSocket服务器通常需要自己的套接字地址(端口号)(可以通过反向代理WebSocket服务器来解决)。Websocket Rails似乎通过连接到现有的基于EventMachine的web服务器(Unicorn不提供)来绕过这一限制。

我想知道是否有人可以提供有关此主题的更多信息。我目前在heroku、unicorn和websocket rails方面遇到了同样的问题。@DavidHahn,在我花费任何时间尝试配置unicorn以使用websocket rails之前,我最终切换到瘦,以线程模式运行。hi@XA21X,尝试使用您的解决方案来使用PUMA,但不起作用,您能看一下吗?