Class: Bayeux
- Inherits:
-
Sinatra::Base
- Object
- Sinatra::Base
- Bayeux
- Defined in:
- lib/bayeux.rb
Overview
A Sinatra application that handles PUTs and POSTs on the /cometd URL, implementing the COMET protocol.
Defined Under Namespace
Classes: Client
Constant Summary collapse
- VERSION =
The Gem version of this implementation
"0.6.2"
Instance Method Summary collapse
-
#channels ⇒ Object
A Hash of channels by channel name.
-
#clients ⇒ Object
A Hash of all clients by clientId.
-
#deliver(message) ⇒ Object
Handle a request from a client.
-
#next_client_id ⇒ Object
ClientIds should be strong random numbers containing at least 128 bits of entropy.
-
#publish(message) ⇒ Object
Send a message (a Hash) to a channel.
-
#respond(messages) ⇒ Object
Send an asynchronous JSON or JSONP response to an async_sinatra GET or POST.
-
#trace(s) ⇒ Object
Trace to stdout if the :tracing setting is enabled.
Instance Method Details
#channels ⇒ Object
A Hash of channels by channel name. Each channel is an Array of subscribed clients
77 78 79 80 |
# File 'lib/bayeux.rb', line 77 def channels # Sinatra dup's this object, so we have to use class variables @@channels ||= Hash.new {|h, k| h[k] = [] } end |
#clients ⇒ Object
A Hash of all clients by clientId
83 84 85 |
# File 'lib/bayeux.rb', line 83 def clients @@clients ||= {} end |
#deliver(message) ⇒ Object
Handle a request from a client. Normally over-ridden in the subclass to add server behaviour.
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/bayeux.rb', line 109 def deliver() id = ['id'] clientId = ['clientId'] channel_name = ['channel'] response = case channel_name when '/meta/handshake' # Client says hello, greet them clientId = next_client_id clients[clientId] = Client.new(clientId) trace "Client #{clientId} offers a handshake from #{request.ip}" handshake when '/meta/subscribe' # Client wants to subscribe to a channel: subscribe when '/meta/unsubscribe' # Client wants to unsubscribe from a channel: unsubscribe # This is the long-polling request. when '/meta/connect' connect when '/meta/disconnect' disconnect # Other meta channels are disallowed when %r{/meta/(.*)} trace "Client #{clientId} tried to send a message to #{channel_name}" { :successful => false } # Service channels default to no-op. Service messages are never broadcast. when %r{/service/(.*)} trace "Client #{clientId} sent a private message to #{channel_name}" { :successful => true } else puts "Unknown channel in request: "+.inspect pass # 404 end # Set the standard parameters for all response messages if response response[:channel] = channel_name response[:clientId] = clientId response[:id] = id [response] else [] end end |
#next_client_id ⇒ Object
ClientIds should be strong random numbers containing at least 128 bits of entropy. These aren’t!
88 89 90 91 92 93 94 |
# File 'lib/bayeux.rb', line 88 def next_client_id begin id = (rand*1_000_000_000).to_i end until !clients[id] trace "New client recieves ID #{id}" id end |
#publish(message) ⇒ Object
Send a message (a Hash) to a channel. The message must have the channel name under the key :channel or “channel”
98 99 100 101 102 103 104 105 106 |
# File 'lib/bayeux.rb', line 98 def publish channel = ['channel'] || [:channel] clients = channels[channel] trace "publishing to #{channel} with #{clients.size} subscribers: #{.inspect}" clients.each do | client| client.queue << client.channel.push true # Wake up the subscribed client end end |
#respond(messages) ⇒ Object
Send an asynchronous JSON or JSONP response to an async_sinatra GET or POST
162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/bayeux.rb', line 162 def respond if jsonp = params['jsonp'] trace "responding jsonp=#{.to_json}" headers({'Content-Type' => 'text/javascript'}) body "#{jsonp}(#{.to_json});\n" else trace "responding #{.to_json}" headers({'Content-Type' => 'application/json'}) body .to_json end end |
#trace(s) ⇒ Object
Trace to stdout if the :tracing setting is enabled
70 71 72 73 74 |
# File 'lib/bayeux.rb', line 70 def trace s if settings.tracing puts s end end |