>情况
我使用 Chrome 的远程调试协议连接到 WebSocket,使用 Rails 应用程序和实现赛璐珞的类,或者更具体地说,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)
但我认为这是委托的?至少
.text
方法也有效?当我改为调用
terminate
(退出Actor(时,WebSocket仍在后台打开。当我在主代码中创建的
MeasurementConnection
对象上调用terminate
时,它使Actor看起来已死,但仍然不会释放连接。
如何复制
您可以通过使用 --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
,则某些东西仍在连接到它。
当我使用类似于此示例的EventMachine
时,它曾经有效,但不适用于faye/websocket-client
,而是em-websocket-client
。在这里,在停止EM循环(带有EM.stop
(时,WebSocket将再次可用。
我想通了。我使用了 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