Ruby: 连接到远程 WebSocket
Ruby: Connect to remote WebSocket
我正在尝试使用 Celluloid 和基于赛璐珞 (gem 'celluloid-websocket-client') 的 Websocket 客户端连接到远程 websocket。这个客户端对我来说的主要优点是我可以使用 class 方法而不是块形式的回调。
require 'celluloid/websocket/client'
class WSConnection
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"
end
# When raw WebSocket message is received
def on_message(msg)
puts "Received message: #{msg}"
end
# When WebSocket is closed
def on_close(code, reason)
puts "WebSocket connection closed: #{code.inspect}, #{reason.inspect}"
end
end
m = WSConnection.new('wss://foo.bar')
while true; sleep; end
预期输出是
"Websocket connection opened"
但是,我根本没有得到任何输出。可能是什么问题?
我正在使用
gem 'celluloid-websocket-client', '0.0.2'
rails 4.2.1
ruby 2.1.3
正如您在评论中注意到的那样,gem 没有 SSL
支持。这就是麻烦所在。为了阐述答案,这里有一个解决方案,以及对未来的一些后续步骤:
[现在]覆盖Celluloid::WebSocket::Client::Connection
中的方法
这是一个示例注入,可为当前 gem 提供 SSL
支持。我的实际上是高度修改的,但这向您展示了基本的解决方案:
def initialize(url, handler=nil)
@url = url
@handler = handler || Celluloid::Actor.current
#de If you want an auto-start:
start
end
def start
uri = URI.parse(@url)
port = uri.port || (uri.scheme == "ws" ? 80 : 443)
@socket.close rescue nil
@socket = Celluloid::IO::TCPSocket.new(uri.host, port)
@socket = Celluloid::IO::SSLSocket.new(@socket) if port == 443
@socket.connect
@client = ::WebSocket::Driver.client(self)
async.run
end
以上通过其他方法发送连锁反应,例如,@handler
用于保存调用 actor,它也有发射器方法。就像我说的,我的版本与原版 gem 非常不同,因为我受够了它并重新设计了我的版本。但是然后:
[很快] 使用Reel::IO::Client
并避免接近某些脑损伤。
WebSocket
支持正在发生令人兴奋的事情,gem 即将重构 websockets 的服务器和客户端实现。不再需要猴子补丁!
所有 websocket 功能都从 Reel
中提取并与 websocket-driver
抽象相结合,如 Reel::IO
... ::Server
和 ::Client
品种。
有趣的是,这是由 Rails
提示的,它正在从 EventMachine
移动到 Celluloid::IO
for websockets:
- https://github.com/rails/actioncable/issues/16
- https://github.com/celluloid/reel/issues/201
- https://github.com/celluloid/reel-io/issues/2
A prealpha is online for preview: https://github.com/celluloid/reel-io
我正在尝试使用 Celluloid 和基于赛璐珞 (gem 'celluloid-websocket-client') 的 Websocket 客户端连接到远程 websocket。这个客户端对我来说的主要优点是我可以使用 class 方法而不是块形式的回调。
require 'celluloid/websocket/client'
class WSConnection
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"
end
# When raw WebSocket message is received
def on_message(msg)
puts "Received message: #{msg}"
end
# When WebSocket is closed
def on_close(code, reason)
puts "WebSocket connection closed: #{code.inspect}, #{reason.inspect}"
end
end
m = WSConnection.new('wss://foo.bar')
while true; sleep; end
预期输出是
"Websocket connection opened"
但是,我根本没有得到任何输出。可能是什么问题?
我正在使用
gem 'celluloid-websocket-client', '0.0.2'
rails 4.2.1
ruby 2.1.3
正如您在评论中注意到的那样,gem 没有 SSL
支持。这就是麻烦所在。为了阐述答案,这里有一个解决方案,以及对未来的一些后续步骤:
[现在]覆盖Celluloid::WebSocket::Client::Connection
中的方法
这是一个示例注入,可为当前 gem 提供 SSL
支持。我的实际上是高度修改的,但这向您展示了基本的解决方案:
def initialize(url, handler=nil)
@url = url
@handler = handler || Celluloid::Actor.current
#de If you want an auto-start:
start
end
def start
uri = URI.parse(@url)
port = uri.port || (uri.scheme == "ws" ? 80 : 443)
@socket.close rescue nil
@socket = Celluloid::IO::TCPSocket.new(uri.host, port)
@socket = Celluloid::IO::SSLSocket.new(@socket) if port == 443
@socket.connect
@client = ::WebSocket::Driver.client(self)
async.run
end
以上通过其他方法发送连锁反应,例如,@handler
用于保存调用 actor,它也有发射器方法。就像我说的,我的版本与原版 gem 非常不同,因为我受够了它并重新设计了我的版本。但是然后:
[很快] 使用Reel::IO::Client
并避免接近某些脑损伤。
WebSocket
支持正在发生令人兴奋的事情,gem 即将重构 websockets 的服务器和客户端实现。不再需要猴子补丁!
所有 websocket 功能都从 Reel
中提取并与 websocket-driver
抽象相结合,如 Reel::IO
... ::Server
和 ::Client
品种。
有趣的是,这是由 Rails
提示的,它正在从 EventMachine
移动到 Celluloid::IO
for websockets:
- https://github.com/rails/actioncable/issues/16
- https://github.com/celluloid/reel/issues/201
- https://github.com/celluloid/reel-io/issues/2
A prealpha is online for preview: https://github.com/celluloid/reel-io