![](/img/trans.png)
[英]How to send a keep-alive packet through websocket in ruby on rails
[英]Ruby - Send message to a Websocket
如何在后台進程中使用Ruby將數據發送到WebSocket?
背景
我已經有一個使用websocket-eventmachine-server
gem運行Websocket服務器的單獨ruby文件。 但是,在我的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工作人員:
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服務器:
您可以將Iodine用作一個簡單的websocket客戶端進行測試。 它使用自己的基於reactor模式的代碼運行后台任務,並有一個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
PS
我建議為你的websockets使用一個框架,比如Plezi (我是作者)。 一些框架允許你在Rails / Sinatra應用程序中運行他們的代碼(Plezi這樣做,我認為Faye雖然不是嚴格意義上的框架,但也是如此)。
直接使用EM是非常核心的,在處理Websockets時需要管理很多東西,一個好的框架可以幫助您管理。
編輯3 :
從Iodine 0.7.17開始支持(重新)支持Iodine 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 :
這個答案現在已經過時了,因為Iodine 0.2.x不再包括客戶了。
對於websocket客戶端使用碘0.1.x或不同的gem
。
websocket-eventmachine-server
是一個websockets 服務器 。
如果你想使用ruby連接到websocket服務器,你可以用一些寶石來做,比如
https://github.com/igrigorik/em-websocket
:服務器和客戶端,也基於eventmachine。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.