2

情况

我通过 Chrome 的远程调试协议连接到一个 WebSocket ,使用 Rails 应用程序和一个实现赛璐珞的类,或者更具体地说,celluloid-websocket-client.

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

当actor内部发生错误但主程序运行时,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)
    

    但我认为这是委派的?至少该.text方法也有效?

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

  • 当我调用我在主代码中创建terminateMeasurementConnection对象时,它使 Actor 看起来死了,但仍然没有释放连接。

如何重现

您可以通过使用--remote-debugging-port=9222命令行参数启动 Chrome,然后检查curl http://localhost:9222/jsonwebSocketDebuggerUrl从那里使用,例如:

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

如果没有webSocketDebuggerUrl可用的,那么某些东西仍在连接到它。

当我使用EventMachine类似于此示例时,它曾经可以工作,但不是与faye/websocket-client,而是em-websocket-client相反。在这里,在停止 EM 循环后(使用EM.stop),WebSocket 将再次可用。

4

1 回答 1

1

我想到了。celluloid-websocket-client我使用了没有委托close方法的 gem 的 0.0.1 版本。

使用 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
于 2014-12-23T08:51:43.700 回答