gpt4 book ai didi

ruby-on-rails - Ruby - 向 Websocket 发送消息

转载 作者:数据小太阳 更新时间:2023-10-29 07:56:25 25 4
gpt4 key购买 nike

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

背景

我已经有一个单独的 ruby​​ 文件运行一个 Websocket 服务器使用 websocket-eventmachine-server gem 。但是,在我的 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 服务器:

您可以使用 Iodine作为用于测试的简单 websocket 客户端。它使用自己的基于 react 堆模式的代码运行后台任务,并有一个 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:

从 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 客户端使用 Iodine 0.1.x 或不同的 gem

关于ruby-on-rails - Ruby - 向 Websocket 发送消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16920792/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com