使用Celluloid正常断开WebSocket连接

时间:2014-12-22 13:37:48

标签: ruby websocket google-chrome-devtools eventmachine celluloid

情况

我使用Chrome的Remote Debugging Protocol连接到WebSocket,使用Rails应用程序和实现Celluloid的类,或者更具体地说,celluloid-websocket-client

问题是我不知道如何干净地断开WebSocket。

当演员内部发生错误但主程序运行时,Chrome会以某种方式使WebSocket无法使用,不允许我再次附加。

代码示例

这里是代码,完全独立:

require 'celluloid/websocket/client'

class MeasurementConnection

  include Celluloid

  def initialize(url)
    @ws_client = Celluloid::WebSocket::Client.new url, Celluloid::Actor.current
  end

  # When WebSocket is opened, register callbacks
  def on_open
    puts "Websocket connection opened"
    # @ws_client.close to close it
  end

  # When raw WebSocket message is received
  def on_message(msg)
    puts "Received message: #{msg}"
  end

  # Send a raw WebSocket message
  def send_chrome_message(msg)
    @ws_client.text JSON.dump msg
  end

  # When WebSocket is closed
  def on_close(code, reason)
    puts "WebSocket connection closed: #{code.inspect}, #{reason.inspect}"
  end

end

MeasurementConnection.new ARGV[0].strip.gsub("\"","")
while true
  sleep
end

我尝试了什么

  • 当我取消注释@ws_client.close时,我得到:

    NoMethodError: undefined method `close' for #<Celluloid::CellProxy(Celluloid::WebSocket::Client::Connection:0x3f954f44edf4)
    

    但我想this was delegated?至少.text方法也有效吗?

  • 当我调用terminate代替(退出Actor)时,WebSocket仍然在后台打开。

  • 当我在主代码中创建的terminate对象上调用MeasurementConnection时,它会使Actor显示为死,但仍然无法释放连接。

    < / LI>

如何重现

您可以自行测试,方法是使用--remote-debugging-port=9222作为命令行参数启动Chrome,然后检查curl http://localhost:9222/json并使用webSocketDebuggerUrl,例如:

ruby chrome-test.rb $(curl http://localhost:9222/json 2>/dev/null | grep webSocket | cut -d ":" -f2-)

如果没有webSocketDebuggerUrl可用,那么某些内容仍然可以连接到它。

以前我使用的EventMachinethis example相似,但不是faye/websocket-client,而是em-websocket-client。这里,在停止EM循环(使用EM.stop)后,WebSocket将再次可用。

1 个答案:

答案 0 :(得分:1)

我明白了。我使用了celluloid-websocket-client gem的0.0.1版本,它没有委托close方法。

使用0.0.2工作,代码如下所示:

MeasurementConnection

def close
  @ws_client.close
end

在主要代码中:

m = MeasurementConnection.new ARGV[0].strip.gsub("\"","")
m.close
while m.alive?
  m.terminate
  sleep(0.01)
end