How to send a keep-alive packet through websocket in ruby on rails

坚强是说给别人听的谎言 提交于 2019-12-05 01:56:06

问题


I want to send a

"Keep alive from client"

message every 30 seconds for my websocket connection. Here's what the code that I have in my websocket initializer looks like:

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

Without any sort of 'keep alive', the connect closes in about 45 seconds. How should I send the 'heart-beat' packet? It seems that the connection is closed by their server, not mine.


回答1:


You can use Websocket Eventmachine Client gem to send hearbeat:

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

You can setup timer for EventMachine with EM::add_periodic_timer(interval_in_seconds), and then send your heartbeat with it.




回答2:


You can use the auto-ping feature (its default and can't be turned off) if you're using Iodine's Websocket client:

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

It's a fairly basic client, but also easy to manage.

EDIT

Iodine also includes some cookie and custom header's support, as now seen in Iodine's documentation. So it's possible to use different authentication techniques (authentication headers or cookies).



来源:https://stackoverflow.com/questions/31819558/how-to-send-a-keep-alive-packet-through-websocket-in-ruby-on-rails

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!