Module: Strelka::WebSocketServer::Heartbeat
- Extended by:
- Loggability, Plugin
- Includes:
- Mongrel2::WebSocket::Constants, Constants
- Defined in:
- lib/strelka/websocketserver/heartbeat.rb
Overview
Heartbeat logic for Strelka WebSocketServers.
To ping connected clients, and disconnect them after 3 failed pings:
class ChatServer < Strelka::WebSocketServer
plugin :heartbeat
heartbeat_rate 5.0
idle_timeout 15.0
end
Defined Under Namespace
Modules: ClassMethods
Constant Summary collapse
- DEFAULT_HEARTBEAT_RATE =
The default number of seconds between heartbeat events
5.0- DEFAULT_IDLE_TIMEOUT =
The default number of seconds between events before a client is disconnected
15.0
Instance Attribute Summary
Attributes included from Plugin
Instance Method Summary collapse
-
#cull_idle_sockets ⇒ Object
Disconnect any sockets that haven't sent any frames for at least SOCKET_IDLE_TIMEOUT seconds.
-
#ping_all_sockets ⇒ Object
Send a PING frame to all connected sockets.
-
#restart ⇒ Object
Called by Mongrel2::Handler when the server is restarted.
-
#shutdown ⇒ Object
Called by Mongrel2::Handler when the server is shut down.
-
#start_accepting_requests ⇒ Object
Called by Mongrel2::Handler when it starts accepting requests.
-
#start_heartbeat ⇒ Object
Start a thread that will periodically ping connected sockets and remove any connections that don't reply.
-
#stop_heartbeat ⇒ Object
Tell the heartbeat thread to exit.
Methods included from Plugin
extended, plugin_name, run_inside, run_outside
Instance Method Details
#cull_idle_sockets ⇒ Object
Disconnect any sockets that haven't sent any frames for at least SOCKET_IDLE_TIMEOUT seconds.
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/strelka/websocketserver/heartbeat.rb', line 120 def cull_idle_sockets self.log.debug "Culling idle sockets." earliest = Time.now - self.class.idle_timeout self.connection_times.each do |sender_id, times| times.each do |conn_id, lastframe| next unless earliest > lastframe self.log.warn "Timing out connection %s:%d: last seen %0.3fs ago." % [ sender_id, conn_id, Time.now - lastframe ] # Make a CLOSE frame frame = Mongrel2::WebSocket::Frame.close frame.set_status( CLOSE_EXCEPTION ) # Use the connection directly so we can send a frame and close the # connection self.conn.send( sender_id, conn_id, frame.to_s ) self.conn.send_close( sender_id, conn_id ) end end end |
#ping_all_sockets ⇒ Object
Send a PING frame to all connected sockets.
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/strelka/websocketserver/heartbeat.rb', line 146 def ping_all_sockets return if self.connections.empty? self.log.debug "Pinging %d connected sockets." % [ self.connections.length ] self.connections.each do |sender_id, conn_ids| frame = Mongrel2::WebSocket::Frame.new( sender_id, conn_id, '', {}, 'heartbeat' ) frame.opcode = :ping frame.fin = true self.log.debug " %s/%d: PING" % [ sender_id, conn_id ] self.conn.reply( frame ) end self.log.debug " done with pings." end |
#restart ⇒ Object
Called by Mongrel2::Handler when the server is restarted. Overridden to restart the heartbeat thread.
86 87 88 89 90 |
# File 'lib/strelka/websocketserver/heartbeat.rb', line 86 def restart self.stop_heartbeat super self.start_heartbeat end |
#shutdown ⇒ Object
Called by Mongrel2::Handler when the server is shut down. Overridden to stop the heartbeat thread.
95 96 97 98 |
# File 'lib/strelka/websocketserver/heartbeat.rb', line 95 def shutdown self.stop_heartbeat super end |
#start_accepting_requests ⇒ Object
Called by Mongrel2::Handler when it starts accepting requests. Overridden to start up the heartbeat thread.
78 79 80 81 |
# File 'lib/strelka/websocketserver/heartbeat.rb', line 78 def start_accepting_requests self.start_heartbeat super end |
#start_heartbeat ⇒ Object
Start a thread that will periodically ping connected sockets and remove any connections that don't reply
103 104 105 106 107 108 109 |
# File 'lib/strelka/websocketserver/heartbeat.rb', line 103 def start_heartbeat self.log.info "Starting heartbeat timer." @heartbeat_timer = self.reactor.add_periodic_timer( self.class.heartbeat_rate ) do self.cull_idle_sockets self.ping_all_sockets end end |
#stop_heartbeat ⇒ Object
Tell the heartbeat thread to exit.
113 114 115 |
# File 'lib/strelka/websocketserver/heartbeat.rb', line 113 def stop_heartbeat self.reactor.remove_timer( @heartbeat_timer ) end |