如何在 ruby on rails 中通过 websocket 发送保持活动的数据包
Posted
技术标签:
【中文标题】如何在 ruby on rails 中通过 websocket 发送保持活动的数据包【英文标题】:How to send a keep-alive packet through websocket in ruby on rails 【发布时间】:2015-10-27 11:09:14 【问题描述】:我想发一个
“从客户端保持活动状态”
我的 websocket 连接每 30 秒发送一次消息。这是我在 websocket 初始化程序中的代码:
ws = WebSocket::Client::Simple.connect 'wss://bitcoin.toshi.io/'
ws.on :message do |msg|
rawJson = msg.data
message_response = JSON.parse(rawJson)
end
ws.on :open do
ws.send "\"subscribe\":\"blocks\""
end
ws.on :close do |e|
puts "WEBSOCKET HAS CLOSED #e"
exit 1
end
ws.on :error do |e|
puts "WEBSOCKET ERROR #e"
end
如果没有任何形式的“保持活动”,连接会在大约 45 秒内关闭。我应该如何发送“心跳”数据包?似乎连接是由他们的服务器关闭的,而不是我的。
【问题讨论】:
Keeping the WebSocket connection alive 的可能重复项 类似,但问题不同。由于缺乏响应,我在 toshi 切断连接时遇到了麻烦——如果他们没有这种行为,那么连接将是稳固的。如果我定期发送一条消息说我仍在收听,我可以保持连接有效。 【参考方案1】:您可以使用Websocket Eventmachine Client gem 发送心跳:
require 'websocket-eventmachine-client'
EM.run do
ws = WebSocket::EventMachine::Client.connect(:uri => 'wss://bitcoin.toshi.io/')
puts ws.comm_inactivity_timeout
ws.onopen do
puts "Connected"
end
ws.onmessage do |msg, type|
puts "Received message: #msg"
end
ws.onclose do |code, reason|
puts "Disconnected with status code: #code"
end
EventMachine.add_periodic_timer(15) do
ws.send ""
end
end
你可以用EM::add_periodic_timer(interval_in_seconds)
为EventMachine设置定时器,然后用它发送你的心跳。
【讨论】:
我可以让它工作,直到包括EventMachine.next_tick
,我最终得到error code 1002
。你说我可以在#next_tick
查看当前时间是什么意思?
@Skull1234567 我修正了我的答案。你实际上应该使用#add_periodic_timer
而不是#next_tick
——现在它可以工作了。
如何关闭此连接以及如何停止周期性计时器?【参考方案2】:
如果您使用Iodine's Websocket 客户端,您可以使用自动 ping 功能(默认且无法关闭):
require 'iodine/http'
# prevents the Iodine's server from running
Iodine.protocol = :timer
# starts Iodine while the script is still running
Iodine.force_start!
# set pinging to a 40 seconds interval.
Iodine::Http::Websockets.default_timeout = 40
settings =
# set's the #on_open event callback.
settings[:on_open] = Proc.new do
write 'sending this connection string.'
end
# set's the #on_message(data) event callback.
settings[:on_message] = Proc.new |data| puts "Received message: #data"
# connects to the websocket
Iodine::Http.ws_connect 'ws://localhost:8080', settings
这是一个相当基本的客户端,但也易于管理。
编辑
Iodine 还包括一些 cookie 和自定义标头的支持,如现在在 Iodine's documentation 中所见。因此可以使用不同的身份验证技术(身份验证标头或 cookie)。
【讨论】:
对不起,如果这是一个新手问题,但是一旦连接,我如何发送ws.send "\"subscribe\":\"blocks\""
类型的消息?
@Skull1234567 - 不用担心。我更新了我的答案。您使用 websocket 对象(事件对象)来发送数据或关闭连接。您可以找到Websocket event object here 的文档。以上是关于如何在 ruby on rails 中通过 websocket 发送保持活动的数据包的主要内容,如果未能解决你的问题,请参考以下文章
在 ruby on rails 3 中通过电子邮件创建订阅
在 Ubuntu 上为 Ruby on Rails 安装 PostgreSQL