Ruby:连接远程WebSocket

6

我正在尝试使用基于Celluloid的Websocket客户端(gem 'celluloid-websocket-client')连接远程Websocket。这个客户端对我来说主要的优点是可以使用类方法形式的回调函数,而不是块。

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

你尝试过在应用程序之外连接到WebSocket吗?例如,从浏览器控制台中连接。 - andHapp
@andHapp 我尝试了浏览器和传统客户端(如 em-websocket)在我的应用程序中,它都运行良好。 - Ilya Cherevkov
我最近没有足够的时间来给出完整的答案,但我想让你知道我会回来为你解决这个问题。 - digitalextremist
@digitalextremist 谢谢,我已经解决了。问题出在 celluloid-websocket-client 本身上。它无法正确处理 SSL Sockets,我已经提交了 pull commit https://github.com/jeremyd/celluloid-websocket-client/pull/15 - Ilya Cherevkov
我也遇到了这个问题。我来回答SSL问题,并看到你已经注意到了它。你介意回答自己的问题并接受你的答案吗?我会关注“celluloid”标签中未回答的问题,而这个问题现在排在首位 :) 实际上,我将提交一个带有补丁的答案,并提供如何在库更改时应对此问题的说明。 - digitalextremist
显示剩余2条评论
1个回答

5

正如您在评论中所注意到的那样,这个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用于保存调用者,它还具有发射器方法。就像我说的那样,我的版本与原始宝石非常不同,因为我厌倦了它并重新制作了我的版本。但是:

[即将]使用Reel::IO::Client避免近乎必定的脑损伤。

WebSocket支持正在进行令人兴奋的事情,一个宝石正在重构服务器和客户端实现的websocket。不再需要猴子补丁!

所有websocket功能都从Reel中提取出来,并与websocket-driver抽象相结合,成为Reel::IO...在两个::Server::Client变体中。

有趣的是,这是由Rails引发的,Rasils正在移动离开EventMachine,转向Celluloid::IO以便处理websocket:

预阿尔法版在线预览:https://github.com/celluloid/reel-io


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接