发送消息到Websocket



如何在后台进程中使用Ruby向WebSocket发送数据?

背景

我已经有一个单独的ruby文件运行使用websocket-eventmachine-server gem的Websocket服务器。然而,在我的Rails应用程序中,我想在后台任务中向websocket发送数据。

这是我的WebSocket服务器:
EM.run do
  trap('TERM') { stop }
  trap('INT') { stop }
  WebSocket::EventMachine::Server.start(host: options[:host], port: options[:port]) do |ws|
    ws.onopen do
      puts 'Client connected'
    end
    ws.onmessage do |msg, type|
      ws.send msg, type: type
    end
    ws.onclose do
      puts 'Client disconnected'
    end
  end
  def stop
    puts 'Terminating WebSocket Server'
    EventMachine.stop
  end
end

然而,在我的后台进程(我使用Sidekiq),我不确定如何连接到WebSocket和发送数据给它。

这是我的Sidekiq worker:

class MyWorker
  include Sidekiq::Worker
  def perform(command)
    100.times do |i|
      # Send 'I am on #{i}' to the Websocket
    end  
  end
end

我希望能够做一些像EventMachine::WebSocket.send 'My message!',但我没有看到一个API或类似的东西。在Ruby中发送数据到WebSocket的正确方法是什么?

接受答案:

如果你保持当前的websocket服务器:

您可以使用碘作为一个简单的websocket客户端进行测试。它使用自己的基于反应器模式的代码运行后台任务,并有一个websocket客户端(我有偏见,我是作者)。

你可以这样做:

require 'iodine/http'
Iodine.protocol = :timers
# force Iodine to start immediately
Iodine.force_start!
options = {}
options[:on_message] = Proc.new {|data| puts data}
100.times do |i|
    options[:on_open] = Proc.new {write "I am number #{i}"}
    Iodine.run do
        Iodine::Http.ws_connect('ws://localhost:3000', options) 
    end
end

公立小学

我建议使用框架,如Plezi,为您的websockets(我是作者)。一些框架允许你在Rails/Sinatra应用程序中运行他们的代码(Plezi这样做,我认为Faye,虽然不是严格的框架,也这样做)。

直接使用EM是相当硬核的,当处理Websockets时,有很多事情需要管理,一个好的框架可以帮助你管理。

编辑3 :

从碘0.7.17开始(重新)支持碘WebSocket客户端连接,包括OpenSSL >= 1.1.0时的TLS连接。

以下代码是原始答案的更新版本:

require 'iodine'
class MyClient
  def on_open connection
    connection.subscribe :updates
    puts "Connected"
  end
  def on_message connection, data
    puts data
  end
  def on_close connection
    # auto-reconnect after 250ms.
    puts "Connection lost, re-connecting in 250ms"
    Iodine.run_after(250) { MyClient.connect }
  end
  def self.connect
    Iodine.connect(url: "ws://localhost:3000/path", handler: MyClient.new)
  end
end

Iodine.threads = 1
Iodine.defer { MyClient.connect if Iodine.master? }
Thread.new { Iodine.start }
100.times {|i| Iodine.publish :updates, "I am number #{i}" }

编辑2 :

这个答案现在已经过时了,因为碘0.2。X不再包含客户端。使用碘酒0.1。.

websocket-eventmachine-server是websockets 服务器

如果你想用ruby连接websocket服务器,你可以使用一些gem,比如

  • https://github.com/igrigorik/em-websocket:服务器和客户端,同样基于eventmachine.

  • ruby-websocket-client: Client only

相关内容

  • 没有找到相关文章