_bushido-faye 0.8.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +247 -0
- data/README.rdoc +92 -0
- data/lib/faye-browser-min.js +1 -0
- data/lib/faye.rb +121 -0
- data/lib/faye/adapters/rack_adapter.rb +210 -0
- data/lib/faye/engines/connection.rb +60 -0
- data/lib/faye/engines/memory.rb +112 -0
- data/lib/faye/engines/proxy.rb +111 -0
- data/lib/faye/error.rb +49 -0
- data/lib/faye/mixins/logging.rb +47 -0
- data/lib/faye/mixins/publisher.rb +30 -0
- data/lib/faye/mixins/timeouts.rb +22 -0
- data/lib/faye/protocol/channel.rb +124 -0
- data/lib/faye/protocol/client.rb +378 -0
- data/lib/faye/protocol/extensible.rb +43 -0
- data/lib/faye/protocol/grammar.rb +58 -0
- data/lib/faye/protocol/publication.rb +5 -0
- data/lib/faye/protocol/server.rb +282 -0
- data/lib/faye/protocol/subscription.rb +24 -0
- data/lib/faye/transport/http.rb +76 -0
- data/lib/faye/transport/local.rb +22 -0
- data/lib/faye/transport/transport.rb +115 -0
- data/lib/faye/transport/web_socket.rb +99 -0
- data/lib/faye/util/namespace.rb +20 -0
- data/spec/browser.html +45 -0
- data/spec/encoding_helper.rb +7 -0
- data/spec/install.sh +78 -0
- data/spec/javascript/channel_spec.js +15 -0
- data/spec/javascript/client_spec.js +714 -0
- data/spec/javascript/engine/memory_spec.js +7 -0
- data/spec/javascript/engine_spec.js +417 -0
- data/spec/javascript/faye_spec.js +15 -0
- data/spec/javascript/grammar_spec.js +66 -0
- data/spec/javascript/node_adapter_spec.js +307 -0
- data/spec/javascript/publisher_spec.js +27 -0
- data/spec/javascript/server/connect_spec.js +168 -0
- data/spec/javascript/server/disconnect_spec.js +121 -0
- data/spec/javascript/server/extensions_spec.js +60 -0
- data/spec/javascript/server/handshake_spec.js +145 -0
- data/spec/javascript/server/integration_spec.js +124 -0
- data/spec/javascript/server/publish_spec.js +85 -0
- data/spec/javascript/server/subscribe_spec.js +247 -0
- data/spec/javascript/server/unsubscribe_spec.js +245 -0
- data/spec/javascript/server_spec.js +110 -0
- data/spec/javascript/transport_spec.js +130 -0
- data/spec/node.js +55 -0
- data/spec/phantom.js +17 -0
- data/spec/ruby/channel_spec.rb +17 -0
- data/spec/ruby/client_spec.rb +724 -0
- data/spec/ruby/engine/memory_spec.rb +7 -0
- data/spec/ruby/engine_examples.rb +427 -0
- data/spec/ruby/faye_spec.rb +14 -0
- data/spec/ruby/grammar_spec.rb +68 -0
- data/spec/ruby/publisher_spec.rb +27 -0
- data/spec/ruby/rack_adapter_spec.rb +236 -0
- data/spec/ruby/server/connect_spec.rb +170 -0
- data/spec/ruby/server/disconnect_spec.rb +120 -0
- data/spec/ruby/server/extensions_spec.rb +68 -0
- data/spec/ruby/server/handshake_spec.rb +143 -0
- data/spec/ruby/server/integration_spec.rb +126 -0
- data/spec/ruby/server/publish_spec.rb +81 -0
- data/spec/ruby/server/subscribe_spec.rb +247 -0
- data/spec/ruby/server/unsubscribe_spec.rb +247 -0
- data/spec/ruby/server_spec.rb +110 -0
- data/spec/ruby/transport_spec.rb +134 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/testswarm +29 -0
- data/spec/thin_proxy.rb +37 -0
- metadata +302 -0
@@ -0,0 +1,43 @@
|
|
1
|
+
module Faye
|
2
|
+
module Extensible
|
3
|
+
include Logging
|
4
|
+
|
5
|
+
def add_extension(extension)
|
6
|
+
@extensions ||= []
|
7
|
+
@extensions << extension
|
8
|
+
extension.added(self) if extension.respond_to?(:added)
|
9
|
+
end
|
10
|
+
|
11
|
+
def remove_extension(extension)
|
12
|
+
return unless @extensions
|
13
|
+
@extensions.delete_if do |ext|
|
14
|
+
next false unless ext == extension
|
15
|
+
extension.removed(self) if extension.respond_to?(:removed)
|
16
|
+
true
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def pipe_through_extensions(stage, message, &callback)
|
21
|
+
debug 'Passing through ? extensions: ?', stage, message
|
22
|
+
|
23
|
+
return callback.call(message) unless @extensions
|
24
|
+
extensions = @extensions.dup
|
25
|
+
|
26
|
+
pipe = lambda do |message|
|
27
|
+
next callback.call(message) unless message
|
28
|
+
|
29
|
+
extension = extensions.shift
|
30
|
+
next callback.call(message) unless extension
|
31
|
+
|
32
|
+
if extension.respond_to?(stage)
|
33
|
+
extension.__send__(stage, message, pipe)
|
34
|
+
else
|
35
|
+
pipe.call(message)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
pipe.call(message)
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Faye
|
2
|
+
module Grammar
|
3
|
+
|
4
|
+
def self.rule(&block)
|
5
|
+
source = instance_eval(&block)
|
6
|
+
%r{^#{string(source)}$}
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.choice(*list)
|
10
|
+
'(' + list.map(&method(:string)) * '|' + ')'
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.repeat(*pattern)
|
14
|
+
'(' + string(pattern) + ')*'
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.oneormore(*pattern)
|
18
|
+
'(' + string(pattern) + ')+'
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.string(item)
|
22
|
+
return item.map(&method(:string)) * '' if Array === item
|
23
|
+
String === item ? item : item.source.gsub(/^\^/, '').gsub(/\$$/, '')
|
24
|
+
end
|
25
|
+
|
26
|
+
LOWALPHA = rule {[ '[a-z]' ]}
|
27
|
+
UPALPHA = rule {[ '[A-Z]' ]}
|
28
|
+
ALPHA = rule {[ choice(LOWALPHA, UPALPHA) ]}
|
29
|
+
DIGIT = rule {[ '[0-9]' ]}
|
30
|
+
ALPHANUM = rule {[ choice(ALPHA, DIGIT) ]}
|
31
|
+
MARK = rule {[ choice(*%w[\\- \\_ \\! \\~ \\( \\) \\$ \\@]) ]}
|
32
|
+
STRING = rule {[ repeat(choice(ALPHANUM, MARK, ' ', '\\/', '\\*', '\\.')) ]}
|
33
|
+
TOKEN = rule {[ oneormore(choice(ALPHANUM, MARK)) ]}
|
34
|
+
INTEGER = rule {[ oneormore(DIGIT) ]}
|
35
|
+
|
36
|
+
CHANNEL_SEGMENT = rule {[ TOKEN ]}
|
37
|
+
CHANNEL_SEGMENTS = rule {[ CHANNEL_SEGMENT, repeat('\\/', CHANNEL_SEGMENT) ]}
|
38
|
+
CHANNEL_NAME = rule {[ '\\/', CHANNEL_SEGMENTS ]}
|
39
|
+
|
40
|
+
WILD_CARD = rule {[ '\\*{1,2}' ]}
|
41
|
+
CHANNEL_PATTERN = rule {[ repeat('\\/', CHANNEL_SEGMENT), '\\/', WILD_CARD ]}
|
42
|
+
|
43
|
+
VERSION_ELEMENT = rule {[ ALPHANUM, repeat(choice(ALPHANUM, '\\-', '\\_')) ]}
|
44
|
+
VERSION = rule {[ INTEGER, repeat('\\.', VERSION_ELEMENT) ]}
|
45
|
+
|
46
|
+
CLIENT_ID = rule {[ oneormore(ALPHANUM) ]}
|
47
|
+
|
48
|
+
ID = rule {[ oneormore(ALPHANUM) ]}
|
49
|
+
|
50
|
+
ERROR_MESSAGE = rule {[ STRING ]}
|
51
|
+
ERROR_ARGS = rule {[ STRING, repeat(',', STRING) ]}
|
52
|
+
ERROR_CODE = rule {[ DIGIT, DIGIT, DIGIT ]}
|
53
|
+
ERROR = rule {[ choice(string([ERROR_CODE, ':', ERROR_ARGS, ':', ERROR_MESSAGE]),
|
54
|
+
string([ERROR_CODE, ':', ':', ERROR_MESSAGE])) ]}
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
@@ -0,0 +1,282 @@
|
|
1
|
+
module Faye
|
2
|
+
class Server
|
3
|
+
|
4
|
+
include Logging
|
5
|
+
include Extensible
|
6
|
+
|
7
|
+
attr_reader :engine
|
8
|
+
|
9
|
+
def initialize(options = {})
|
10
|
+
@options = options || {}
|
11
|
+
engine_opts = @options[:engine] || {}
|
12
|
+
engine_opts[:timeout] = @options[:timeout]
|
13
|
+
@engine = Faye::Engine.get(engine_opts)
|
14
|
+
|
15
|
+
info 'Created new server: ?', @options
|
16
|
+
end
|
17
|
+
|
18
|
+
def flush_connection(messages)
|
19
|
+
client_id = Faye.client_id_from_messages(messages)
|
20
|
+
info 'Flushing connection for ?', client_id
|
21
|
+
@engine.flush(client_id) if client_id
|
22
|
+
end
|
23
|
+
|
24
|
+
def open_socket(client_id, socket)
|
25
|
+
@engine.open_socket(client_id, socket)
|
26
|
+
end
|
27
|
+
|
28
|
+
def close_socket(client_id)
|
29
|
+
@engine.flush(client_id)
|
30
|
+
end
|
31
|
+
|
32
|
+
def process(messages, local = false, &callback)
|
33
|
+
messages = [messages].flatten
|
34
|
+
info 'Processing messages: ? (local: ?)', messages, local
|
35
|
+
|
36
|
+
return callback.call([]) if messages.size == 0
|
37
|
+
processed, responses = 0, []
|
38
|
+
|
39
|
+
gather_replies = lambda do |replies|
|
40
|
+
responses.concat(replies)
|
41
|
+
processed += 1
|
42
|
+
responses.compact!
|
43
|
+
info 'Returning replies: ?', responses
|
44
|
+
callback.call(responses) if processed == messages.size
|
45
|
+
end
|
46
|
+
|
47
|
+
handle_reply = lambda do |replies|
|
48
|
+
extended, expected = 0, replies.size
|
49
|
+
gather_replies.call(replies) if expected == 0
|
50
|
+
|
51
|
+
replies.each_with_index do |reply, i|
|
52
|
+
debug 'Processing reply: ?', reply
|
53
|
+
pipe_through_extensions(:outgoing, reply) do |message|
|
54
|
+
replies[i] = message
|
55
|
+
extended += 1
|
56
|
+
gather_replies.call(replies) if extended == expected
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
messages.each do |message|
|
62
|
+
pipe_through_extensions(:incoming, message) do |piped_message|
|
63
|
+
handle(piped_message, local, &handle_reply)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def make_response(message)
|
69
|
+
response = {}
|
70
|
+
|
71
|
+
response['id'] = message['id'] if message['id']
|
72
|
+
response['clientId'] = message['clientId'] if message['clientId']
|
73
|
+
response['channel'] = message['channel'] if message['channel']
|
74
|
+
response['error'] = message['error'] if message['error']
|
75
|
+
|
76
|
+
response['successful'] = !response['error']
|
77
|
+
response
|
78
|
+
end
|
79
|
+
|
80
|
+
def handle(message, local = false, &callback)
|
81
|
+
return callback.call([]) if !message
|
82
|
+
info 'Handling message: ? (local: ?)', message, local
|
83
|
+
|
84
|
+
channel_name = message['channel']
|
85
|
+
error = message['error']
|
86
|
+
|
87
|
+
return handle_meta(message, local, &callback) if Channel.meta?(channel_name)
|
88
|
+
|
89
|
+
if Grammar::CHANNEL_NAME !~ channel_name
|
90
|
+
error = Faye::Error.channel_invalid(channel_name)
|
91
|
+
end
|
92
|
+
|
93
|
+
@engine.publish(message) unless error
|
94
|
+
|
95
|
+
response = make_response(message)
|
96
|
+
response['error'] = error if error
|
97
|
+
response['successful'] = !response['error']
|
98
|
+
callback.call([response])
|
99
|
+
end
|
100
|
+
|
101
|
+
def handle_meta(message, local, &callback)
|
102
|
+
method = Channel.parse(message['channel'])[1]
|
103
|
+
client_id = message['clientId']
|
104
|
+
|
105
|
+
__send__(method, message, local) do |responses|
|
106
|
+
responses = [responses].flatten
|
107
|
+
responses.each { |r| advize(r, message['connectionType']) }
|
108
|
+
callback.call(responses)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def advize(response, connection_type)
|
113
|
+
return unless [Channel::HANDSHAKE, Channel::CONNECT].include?(response['channel'])
|
114
|
+
|
115
|
+
if connection_type == 'eventsource'
|
116
|
+
interval = (@engine.timeout * 1000).floor
|
117
|
+
timeout = 0
|
118
|
+
else
|
119
|
+
interval = (@engine.interval * 1000).floor
|
120
|
+
timeout = (@engine.timeout * 1000).floor
|
121
|
+
end
|
122
|
+
|
123
|
+
advice = response['advice'] ||= {}
|
124
|
+
if response['error']
|
125
|
+
advice['reconnect'] ||= 'handshake'
|
126
|
+
else
|
127
|
+
advice['reconnect'] ||= 'retry'
|
128
|
+
advice['interval'] ||= interval
|
129
|
+
advice['timeout'] ||= timeout
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# MUST contain * version
|
134
|
+
# * supportedConnectionTypes
|
135
|
+
# MAY contain * minimumVersion
|
136
|
+
# * ext
|
137
|
+
# * id
|
138
|
+
def handshake(message, local = false, &callback)
|
139
|
+
response = make_response(message)
|
140
|
+
response['version'] = BAYEUX_VERSION
|
141
|
+
|
142
|
+
response['error'] = Error.parameter_missing('version') if message['version'].nil?
|
143
|
+
|
144
|
+
client_conns = message['supportedConnectionTypes']
|
145
|
+
|
146
|
+
response['supportedConnectionTypes'] = CONNECTION_TYPES
|
147
|
+
|
148
|
+
if client_conns
|
149
|
+
common_conns = client_conns.select { |c| CONNECTION_TYPES.include?(c) }
|
150
|
+
response['error'] = Error.conntype_mismatch(*client_conns) if common_conns.empty?
|
151
|
+
else
|
152
|
+
response['error'] = Error.parameter_missing('supportedConnectionTypes')
|
153
|
+
end
|
154
|
+
|
155
|
+
response['successful'] = response['error'].nil?
|
156
|
+
return callback.call(response) unless response['successful']
|
157
|
+
|
158
|
+
@engine.create_client do |client_id|
|
159
|
+
response['clientId'] = client_id
|
160
|
+
callback.call(response)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
# MUST contain * clientId
|
165
|
+
# * connectionType
|
166
|
+
# MAY contain * ext
|
167
|
+
# * id
|
168
|
+
def connect(message, local = false, &callback)
|
169
|
+
response = make_response(message)
|
170
|
+
client_id = message['clientId']
|
171
|
+
connection_type = message['connectionType']
|
172
|
+
|
173
|
+
@engine.client_exists(client_id) do |exists|
|
174
|
+
response['error'] = Error.client_unknown(client_id) unless exists
|
175
|
+
response['error'] = Error.parameter_missing('clientId') if client_id.nil?
|
176
|
+
|
177
|
+
unless CONNECTION_TYPES.include?(connection_type)
|
178
|
+
response['error'] = Error.conntype_mismatch(connection_type)
|
179
|
+
end
|
180
|
+
|
181
|
+
response['error'] = Error.parameter_missing('connectionType') if connection_type.nil?
|
182
|
+
|
183
|
+
response['successful'] = response['error'].nil?
|
184
|
+
|
185
|
+
if !response['successful']
|
186
|
+
response.delete('clientId')
|
187
|
+
next callback.call(response)
|
188
|
+
end
|
189
|
+
|
190
|
+
if message['connectionType'] == 'eventsource'
|
191
|
+
message['advice'] ||= {}
|
192
|
+
message['advice']['timeout'] = 0
|
193
|
+
end
|
194
|
+
|
195
|
+
@engine.connect(response['clientId'], message['advice']) do |events|
|
196
|
+
callback.call([response] + events)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
# MUST contain * clientId
|
202
|
+
# MAY contain * ext
|
203
|
+
# * id
|
204
|
+
def disconnect(message, local = false, &callback)
|
205
|
+
response = make_response(message)
|
206
|
+
client_id = message['clientId']
|
207
|
+
|
208
|
+
@engine.client_exists(client_id) do |exists|
|
209
|
+
response['error'] = Error.client_unknown(client_id) unless exists
|
210
|
+
response['error'] = Error.parameter_missing('clientId') if client_id.nil?
|
211
|
+
|
212
|
+
response['successful'] = response['error'].nil?
|
213
|
+
response.delete('clientId') unless response['successful']
|
214
|
+
|
215
|
+
@engine.destroy_client(client_id) if response['successful']
|
216
|
+
callback.call(response)
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
# MUST contain * clientId
|
221
|
+
# * subscription
|
222
|
+
# MAY contain * ext
|
223
|
+
# * id
|
224
|
+
def subscribe(message, local = false, &callback)
|
225
|
+
response = make_response(message)
|
226
|
+
client_id = message['clientId']
|
227
|
+
subscription = [message['subscription']].flatten
|
228
|
+
|
229
|
+
@engine.client_exists(client_id) do |exists|
|
230
|
+
response['error'] = Error.client_unknown(client_id) unless exists
|
231
|
+
response['error'] = Error.parameter_missing('clientId') if client_id.nil?
|
232
|
+
response['error'] = Error.parameter_missing('subscription') if message['subscription'].nil?
|
233
|
+
|
234
|
+
response['subscription'] = message['subscription'] || []
|
235
|
+
|
236
|
+
subscription.each do |channel|
|
237
|
+
next if response['error']
|
238
|
+
response['error'] = Error.channel_forbidden(channel) unless local or Channel.subscribable?(channel)
|
239
|
+
response['error'] = Error.channel_invalid(channel) unless Channel.valid?(channel)
|
240
|
+
|
241
|
+
next if response['error']
|
242
|
+
@engine.subscribe(client_id, channel)
|
243
|
+
end
|
244
|
+
|
245
|
+
response['successful'] = response['error'].nil?
|
246
|
+
callback.call(response)
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
# MUST contain * clientId
|
251
|
+
# * subscription
|
252
|
+
# MAY contain * ext
|
253
|
+
# * id
|
254
|
+
def unsubscribe(message, local = false, &callback)
|
255
|
+
response = make_response(message)
|
256
|
+
client_id = message['clientId']
|
257
|
+
subscription = [message['subscription']].flatten
|
258
|
+
|
259
|
+
@engine.client_exists(client_id) do |exists|
|
260
|
+
response['error'] = Error.client_unknown(client_id) unless exists
|
261
|
+
response['error'] = Error.parameter_missing('clientId') if client_id.nil?
|
262
|
+
response['error'] = Error.parameter_missing('subscription') if message['subscription'].nil?
|
263
|
+
|
264
|
+
response['subscription'] = message['subscription'] || []
|
265
|
+
|
266
|
+
subscription.each do |channel|
|
267
|
+
next if response['error']
|
268
|
+
response['error'] = Error.channel_forbidden(channel) unless local or Channel.subscribable?(channel)
|
269
|
+
response['error'] = Error.channel_invalid(channel) unless Channel.valid?(channel)
|
270
|
+
|
271
|
+
next if response['error']
|
272
|
+
@engine.unsubscribe(client_id, channel)
|
273
|
+
end
|
274
|
+
|
275
|
+
response['successful'] = response['error'].nil?
|
276
|
+
callback.call(response)
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Faye
|
2
|
+
class Subscription
|
3
|
+
include EventMachine::Deferrable
|
4
|
+
|
5
|
+
def initialize(client, channels, callback)
|
6
|
+
@client = client
|
7
|
+
@channels = channels
|
8
|
+
@callback = callback
|
9
|
+
@cancelled = false
|
10
|
+
end
|
11
|
+
|
12
|
+
def cancel
|
13
|
+
return if @cancelled
|
14
|
+
@client.unsubscribe(@channels, &@callback)
|
15
|
+
@cancelled = true
|
16
|
+
end
|
17
|
+
|
18
|
+
def unsubscribe
|
19
|
+
cancel
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Faye
|
2
|
+
|
3
|
+
class Transport::Http < Transport
|
4
|
+
def self.usable?(endpoint, &callback)
|
5
|
+
callback.call(endpoint.is_a?(String))
|
6
|
+
end
|
7
|
+
|
8
|
+
def request(message, timeout)
|
9
|
+
retry_block = retry_block(message, timeout)
|
10
|
+
|
11
|
+
content = Faye.to_json(message)
|
12
|
+
cookies = @cookies.get_cookies(@endpoint)
|
13
|
+
params = build_params(URI.parse(@endpoint), content, cookies)
|
14
|
+
request = create_request(params)
|
15
|
+
|
16
|
+
request.callback do
|
17
|
+
handle_response(request.response, retry_block)
|
18
|
+
store_cookies([*request.response_header['SET_COOKIE']].compact)
|
19
|
+
end
|
20
|
+
request.errback do
|
21
|
+
retry_block.call
|
22
|
+
trigger(:down)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def build_params(uri, content, cookies)
|
29
|
+
{
|
30
|
+
:head => {
|
31
|
+
'Content-Length' => content.bytesize,
|
32
|
+
'Content-Type' => 'application/json',
|
33
|
+
'Cookie' => cookies * '; ',
|
34
|
+
'Host' => uri.host
|
35
|
+
}.merge(@headers),
|
36
|
+
|
37
|
+
:body => content,
|
38
|
+
:timeout => -1 # for em-http-request < 1.0
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
def create_request(params)
|
43
|
+
version = EventMachine::HttpRequest::VERSION.split('.')[0].to_i
|
44
|
+
client = if version >= 1
|
45
|
+
options = { # for em-http-request >= 1.0
|
46
|
+
:inactivity_timeout => 0 # connection inactivity (post-setup) timeout (0 = disable timeout)
|
47
|
+
}
|
48
|
+
EventMachine::HttpRequest.new(@endpoint, options)
|
49
|
+
else
|
50
|
+
EventMachine::HttpRequest.new(@endpoint)
|
51
|
+
end
|
52
|
+
|
53
|
+
client.post(params)
|
54
|
+
end
|
55
|
+
|
56
|
+
def handle_response(response, retry_block)
|
57
|
+
message = Yajl::Parser.parse(response) rescue nil
|
58
|
+
if message
|
59
|
+
receive(message)
|
60
|
+
trigger(:up)
|
61
|
+
else
|
62
|
+
retry_block.call
|
63
|
+
trigger(:down)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def store_cookies(cookies)
|
68
|
+
cookies.each do |cookie|
|
69
|
+
@cookies.set_cookie(@endpoint, cookie)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
Transport.register 'long-polling', Transport::Http
|
75
|
+
|
76
|
+
end
|