Faye WebSocket, reconnect to socket after close handler gets triggered
Asked Answered
K

1

6

I have a super simple script that has pretty much what's on the Faye WebSocket GitHub page for handling closed connections:

 ws = Faye::WebSocket::Client.new(url, nil, :headers => headers)

  ws.on :open do |event|
    p [:open]
    # send ping command
    # send test command
    #ws.send({command: 'test'}.to_json)
  end 

  ws.on :message do |event|
    # here is the entry point for data coming from the server.
    p JSON.parse(event.data)
  end 

  ws.on :close do |event|
    # connection has been closed callback.
    p [:close, event.code, event.reason]
    ws = nil 
  end 

Once the client is idle for 2 hours, the server closes the connection. I can't seem to find a way to reconnect to the server once ws.on :close is triggered. Is there an easy way of going about this? I just want it to trigger ws.on :open after :close goes off.

Kan answered 8/4, 2014 at 15:10 Comment(1)
If you want to avoid a timeout: Is it an option to send some dummy data from time to time to the server?Kicksorter
V
10

Looking for the Faye Websocket Client implementation, there is a ping option which sends some data to the server periodically, which prevents the connection to go idle.

# Send ping data each minute
ws = Faye::WebSocket::Client.new(url, nil, headers: headers, ping: 60) 

However, if you don't want to rely on the server behaviour, since it can finish the connection even if you are sending some data periodically, you can just put the client setup inside a method and start all over again if the server closes the connection.

def start_connection
  ws = Faye::WebSocket::Client.new(url, nil, headers: headers, ping: 60)

  ws.on :open do |event|
    p [:open]
  end 

  ws.on :message do |event|
    # here is the entry point for data coming from the server.
    p JSON.parse(event.data)
  end 

  ws.on :close do |event|
    # connection has been closed callback.
    p [:close, event.code, event.reason]

    # restart the connection
    start_connection
  end
end
Vandal answered 10/4, 2014 at 19:31 Comment(5)
Wouldn't this cause an infinitely deep stack upon many retries? I wonder if it's safe to use in a long term deployment.Irritative
No, because this is not a recursion.Vandal
It's definitely a recursion. You can check it by yourself in the terminal: ruby -e 'def start_connection; puts '1'; start_connection; end; start_connection' Pretty soon you will get the error: 2:in puts: stack level too deep (SystemStackError)Veolaver
@Veolaver Is it the same code from 2014?Vandal
@ThiagoLewin Hm. Seems like I made hasty conclusions there. My apologies. Tried your code and it indeed did not raise any exceptions. Don't really understand why, though. Additional explanation would be great.Veolaver

© 2022 - 2024 — McMap. All rights reserved.