class Jebanni::Server
Public Class Methods
new(ip = '127.0.0.1', port = 63310)
click to toggle source
Calls superclass method
# File lib/jebanni/server.rb, line 11 def initialize(ip = '127.0.0.1', port = 63310) @channels = {} super(ip, port, &method(:on_connection)) async.ping end
Public Instance Methods
all_connections()
click to toggle source
# File lib/jebanni/server.rb, line 28 def all_connections @channels.map{|(_, channel)| channel.connections}.flatten end
broadcast_to(channel, data, event, id)
click to toggle source
# File lib/jebanni/server.rb, line 17 def broadcast_to(channel, data, event, id) channel.connections.each do |socket| async.send_sse(socket, data, event, id) end true end
channels()
click to toggle source
# File lib/jebanni/server.rb, line 24 def channels @channels end
Private Instance Methods
event_stream(request, response)
click to toggle source
# File lib/jebanni/server.rb, line 88 def event_stream(request, response) Reel::EventStream.new do |socket| channel = response.channel channel.join socket socket.retry 5000 #after a Connection reset resend newer Messages to the Client, query['lastEventId'] is needed for https://github.com/Yaffle/EventSource query = Hash[URI.decode_www_form(request.query_string || "")] id = (request.headers['Last-Event-ID'] || query['lastEventId']) socket << "id\n\n" if id && id.to_i > 0 channel.refrain(id.to_i) end end end
handle_request(request)
click to toggle source
# File lib/jebanni/server.rb, line 71 def handle_request(request) response = RequestHandler.new(request, self).route! return request.respond 204 if response.finished? request.respond Reel::StreamResponse.new(:ok, response_headers, event_stream(request, response)) end
leave_channel(socket)
click to toggle source
# File lib/jebanni/server.rb, line 45 def leave_channel(socket) @channels.each do |id, ch| next unless ch.connections.include?(socket) debug("Disconnect from channel:#{id}") ch.leave(socket) end end
on_connection(connection)
click to toggle source
# File lib/jebanni/server.rb, line 103 def on_connection(connection) connection.each_request do |request| handle_request(request) end end
ping()
click to toggle source
apache 2.2 closes connections after five seconds when nothing is send, see this as a poor mans Keep-Alive
# File lib/jebanni/server.rb, line 65 def ping every(5) do send_ping end end
response_headers()
click to toggle source
# File lib/jebanni/server.rb, line 78 def response_headers #X-Accel-Buffering is nginx(?) specific. Setting this to "no" will allow unbuffered responses suitable for Comet and HTTP streaming applications { 'Content-Type' => 'text/event-stream; charset=utf-8', 'Cache-Control' => 'no-cache', 'X-Accel-Buffering' => 'no', 'Access-Control-Allow-Origin' => '*', } end
send_ping()
click to toggle source
Lines that start with a Colon are Comments and will be ignored
# File lib/jebanni/server.rb, line 54 def send_ping all_connections.each do |socket| begin socket << ": ping\n" rescue Reel::SocketError leave_channel(socket) end end end
send_sse(socket, data, event = nil, id = nil)
click to toggle source
event and id are optional, Eventsource only needs data
# File lib/jebanni/server.rb, line 34 def send_sse(socket, data, event = nil, id = nil) unless data.is_a? String data = JSON.dump(data) end socket.id id if id socket.event event if event socket.data data rescue Reel::SocketError leave_channel(socket) end