【问题标题】:ActionCable raising exception during rspec system specActionCable 在 rspec 系统规范期间引发异常
【发布时间】:2017-11-15 11:10:33
【问题描述】:

我在使用带有 Capybara 的系统规格的 ActionCable 时遇到问题。 ActionCable 在我的开发服务器上运行良好,但是在使用系统规范进行测试时,它无法连接到 Websocket。

/log/test.log 的输出显示:

Started GET "/cable" for 127.0.0.1 at 2017-11-15 18:17:04 +0900
Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2017-11-15 18:17:04 +0900
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
WebSocket error occurred: undefined method `write_nonblock' for nil:NilClass
WebSocket error occurred: undefined method `write_nonblock' for nil:NilClass
WebSocket error occurred: undefined method `write_nonblock' for nil:NilClass

我正在使用:

  • 红宝石 2.4.1
  • 导轨 5.1.4
  • rspec 3.7.0
  • 水豚2.13.0
  • 彪马3.10.0
  • selenium-webdriver 3.6.0

我试过了:

Capybara.server = :puma

这没有什么区别(可能是因为系统规格已经在使用 Puma)。

我调试问题的尝试:

仔细查看错误,write_nonblock 方法在 nil 上被调用,这发生在第 45 行:

https://github.com/rails/rails/blob/385825fb705446a1f11e82b65ca97a50d7e67898/actioncable/lib/action_cable/connection/stream.rb#L45

似乎@rack_hijack_io 被设置为nil,这很可能发生在hijack_rack_socket 方法中:

https://github.com/rails/rails/blob/385825fb705446a1f11e82b65ca97a50d7e67898/actioncable/lib/action_cable/connection/stream.rb#L102

@socket_object.env["rack.hijack_io"] 返回nil,所以我们没有"rack.hijack_io" 键。所以这个错误似乎与 Rack Hijacking API 有关。

【问题讨论】:

  • 我猜这是 Puma 中的错误,而不是 RSpec 或您的配置中的错误。您可以通过暂时将其替换为thin 来验证这一点。在 git 中创建一个分支并注释掉 gem 'puma' 并在 Gemfile 中添加 gem 'thin'
  • 感谢@max 的建议。我尝试切换到thintest.log 中的错误消失了。但是,我现在得到Error during WebSocket handshake: 'Upgrade' header is missing (stackoverflow.com/questions/37871074/…)。我会尝试看看是否可以让其他服务器工作以将问题隔离到 Puma。
  • config.middleware.delete Rack::Lock 添加到我的environments/test.rb 会从test.log 中删除错误消息。这甚至适用于Puma。我不知道为什么。但是,window.App.cable.subscriptions.create 中的 connected-callback 永远不会被调用 (gist.github.com/andreaslillebo/…)。这适用于development。当使用 selenium 和 chromium 时,在测试运行时打开网络选项卡,它似乎已连接(gist.github.com/andreaslillebo/8ff8d7c022058f5ca21b2935f69a445f
  • Rack::Lock 防止多个同时请求/连接。 Rails 5.1 根本不应该包含它,除非您通过指定 config.allow_concurrency = false 选择退出并发。至于 Puma,它在您的测试运行中会产生什么输出 - 它是否处于“单模式”并且是否声明它正在使用多个线程?

标签: ruby-on-rails ruby rspec capybara actioncable


【解决方案1】:

我不知道有关您的测试的详细信息,但就我而言,问题出在 config.log_level = :debugconfig/environments/[env]

因为 ActionCable 会产生大量关于广播的调试信息。例如,如果您有 100 个连接的客户端,您的日志文件将被每次广播的 100 条消息污染。

PS:我在 NGINX + Passenger(6.0.4) + GKE 上使用 Stackdriver 日志记录发现了这个错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-16
    • 1970-01-01
    相关资源
    最近更新 更多