faye 0.8.11 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of faye might be problematic. Click here for more details.
- data/{History.txt → CHANGELOG.md} +126 -105
- data/README.md +36 -0
- data/lib/faye-browser-min.js +2 -1
- data/lib/faye-browser-min.js.map +1 -8
- data/lib/faye-browser.js +923 -607
- data/lib/faye.rb +11 -5
- data/lib/faye/adapters/rack_adapter.rb +80 -85
- data/lib/faye/engines/connection.rb +7 -9
- data/lib/faye/engines/memory.rb +1 -0
- data/lib/faye/engines/proxy.rb +7 -6
- data/lib/faye/mixins/deferrable.rb +15 -0
- data/lib/faye/mixins/logging.rb +11 -22
- data/lib/faye/mixins/publisher.rb +9 -20
- data/lib/faye/protocol/channel.rb +2 -1
- data/lib/faye/protocol/client.rb +70 -48
- data/lib/faye/protocol/envelope.rb +24 -0
- data/lib/faye/protocol/extensible.rb +7 -4
- data/lib/faye/protocol/publication.rb +1 -1
- data/lib/faye/protocol/server.rb +8 -11
- data/lib/faye/protocol/socket.rb +6 -4
- data/lib/faye/protocol/subscription.rb +1 -1
- data/lib/faye/transport/http.rb +20 -27
- data/lib/faye/transport/local.rb +5 -5
- data/lib/faye/transport/transport.rb +42 -12
- data/lib/faye/transport/web_socket.rb +71 -38
- metadata +169 -137
- checksums.yaml +0 -7
- data/README.rdoc +0 -83
- data/spec/browser.html +0 -45
- data/spec/encoding_helper.rb +0 -7
- data/spec/install.sh +0 -78
- data/spec/javascript/channel_spec.js +0 -15
- data/spec/javascript/client_spec.js +0 -729
- data/spec/javascript/dispatcher_spec.js +0 -122
- data/spec/javascript/engine/memory_spec.js +0 -7
- data/spec/javascript/engine_spec.js +0 -417
- data/spec/javascript/faye_spec.js +0 -34
- data/spec/javascript/grammar_spec.js +0 -66
- data/spec/javascript/node_adapter_spec.js +0 -314
- data/spec/javascript/publisher_spec.js +0 -27
- data/spec/javascript/server/connect_spec.js +0 -168
- data/spec/javascript/server/disconnect_spec.js +0 -121
- data/spec/javascript/server/extensions_spec.js +0 -60
- data/spec/javascript/server/handshake_spec.js +0 -145
- data/spec/javascript/server/integration_spec.js +0 -131
- data/spec/javascript/server/publish_spec.js +0 -85
- data/spec/javascript/server/subscribe_spec.js +0 -247
- data/spec/javascript/server/unsubscribe_spec.js +0 -245
- data/spec/javascript/server_spec.js +0 -121
- data/spec/javascript/transport_spec.js +0 -135
- data/spec/node.js +0 -55
- data/spec/phantom.js +0 -17
- data/spec/ruby/channel_spec.rb +0 -17
- data/spec/ruby/client_spec.rb +0 -741
- data/spec/ruby/engine/memory_spec.rb +0 -7
- data/spec/ruby/engine_examples.rb +0 -427
- data/spec/ruby/faye_spec.rb +0 -30
- data/spec/ruby/grammar_spec.rb +0 -68
- data/spec/ruby/publisher_spec.rb +0 -27
- data/spec/ruby/rack_adapter_spec.rb +0 -241
- data/spec/ruby/server/connect_spec.rb +0 -170
- data/spec/ruby/server/disconnect_spec.rb +0 -120
- data/spec/ruby/server/extensions_spec.rb +0 -68
- data/spec/ruby/server/handshake_spec.rb +0 -143
- data/spec/ruby/server/integration_spec.rb +0 -133
- data/spec/ruby/server/publish_spec.rb +0 -81
- data/spec/ruby/server/subscribe_spec.rb +0 -247
- data/spec/ruby/server/unsubscribe_spec.rb +0 -247
- data/spec/ruby/server_spec.rb +0 -121
- data/spec/ruby/transport_spec.rb +0 -136
- data/spec/spec_helper.rb +0 -11
- data/spec/testswarm +0 -42
- data/spec/thin_proxy.rb +0 -37
@@ -1,28 +1,17 @@
|
|
1
1
|
module Faye
|
2
2
|
module Publisher
|
3
3
|
|
4
|
-
|
5
|
-
return 0 unless @subscribers and @subscribers[event_type]
|
6
|
-
@subscribers[event_type].size
|
7
|
-
end
|
8
|
-
|
9
|
-
def bind(event_type, &listener)
|
10
|
-
@subscribers ||= {}
|
11
|
-
list = @subscribers[event_type] ||= []
|
12
|
-
list << listener
|
13
|
-
end
|
4
|
+
include ::WebSocket::Driver::EventEmitter
|
14
5
|
|
15
|
-
|
16
|
-
|
17
|
-
return @subscribers.delete(event_type) unless listener
|
18
|
-
|
19
|
-
@subscribers[event_type].delete_if(&listener.method(:==))
|
20
|
-
end
|
6
|
+
alias :bind :add_listener
|
7
|
+
alias :trigger :emit
|
21
8
|
|
22
|
-
def
|
23
|
-
|
24
|
-
|
25
|
-
|
9
|
+
def unbind(event, &listener)
|
10
|
+
if listener
|
11
|
+
remove_listener(event, &listener)
|
12
|
+
else
|
13
|
+
remove_all_listeners(event)
|
14
|
+
end
|
26
15
|
end
|
27
16
|
|
28
17
|
end
|
@@ -5,6 +5,7 @@ module Faye
|
|
5
5
|
attr_reader :name
|
6
6
|
|
7
7
|
def initialize(name)
|
8
|
+
super()
|
8
9
|
@name = name
|
9
10
|
end
|
10
11
|
|
@@ -13,7 +14,7 @@ module Faye
|
|
13
14
|
end
|
14
15
|
|
15
16
|
def unused?
|
16
|
-
|
17
|
+
listener_count(:message).zero?
|
17
18
|
end
|
18
19
|
|
19
20
|
HANDSHAKE = '/meta/handshake'
|
data/lib/faye/protocol/client.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Faye
|
2
2
|
class Client
|
3
3
|
|
4
|
-
include
|
4
|
+
include Deferrable
|
5
5
|
include Publisher
|
6
6
|
include Logging
|
7
7
|
include Extensible
|
@@ -17,14 +17,16 @@ module Faye
|
|
17
17
|
|
18
18
|
CONNECTION_TIMEOUT = 60.0
|
19
19
|
DEFAULT_RETRY = 5.0
|
20
|
+
MAX_REQUEST_SIZE = 2048
|
20
21
|
|
21
|
-
attr_reader :
|
22
|
+
attr_reader :cookies, :endpoint, :endpoints, :headers, :max_request_size, :retry, :transports
|
22
23
|
|
23
24
|
def initialize(endpoint = nil, options = {})
|
25
|
+
super()
|
24
26
|
info('New client created for ?', endpoint)
|
25
27
|
|
26
28
|
@options = options
|
27
|
-
@endpoint = endpoint || RackAdapter::DEFAULT_ENDPOINT
|
29
|
+
@endpoint = Faye.parse_url(endpoint || RackAdapter::DEFAULT_ENDPOINT)
|
28
30
|
@endpoints = @options[:endpoints] || {}
|
29
31
|
@transports = {}
|
30
32
|
@cookies = CookieJar::Jar.new
|
@@ -32,6 +34,12 @@ module Faye
|
|
32
34
|
@disabled = []
|
33
35
|
@retry = @options[:retry] || DEFAULT_RETRY
|
34
36
|
|
37
|
+
@endpoints.each do |key, value|
|
38
|
+
@endpoints[key] = Faye.parse_url(value)
|
39
|
+
end
|
40
|
+
|
41
|
+
@max_request_size = MAX_REQUEST_SIZE
|
42
|
+
|
35
43
|
@state = UNCONNECTED
|
36
44
|
@channels = Channel::Set.new
|
37
45
|
@message_id = 0
|
@@ -53,15 +61,6 @@ module Faye
|
|
53
61
|
@headers[name.to_s] = value.to_s
|
54
62
|
end
|
55
63
|
|
56
|
-
def state
|
57
|
-
case @state
|
58
|
-
when UNCONNECTED then :UNCONNECTED
|
59
|
-
when CONNECTING then :CONNECTING
|
60
|
-
when CONNECTED then :CONNECTED
|
61
|
-
when DISCONNECTED then :DISCONNECTED
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
64
|
# Request
|
66
65
|
# MUST include: * channel
|
67
66
|
# * version
|
@@ -91,9 +90,9 @@ module Faye
|
|
91
90
|
select_transport(MANDATORY_CONNECTION_TYPES)
|
92
91
|
|
93
92
|
send({
|
94
|
-
'channel'
|
95
|
-
'version'
|
96
|
-
'supportedConnectionTypes'
|
93
|
+
'channel' => Channel::HANDSHAKE,
|
94
|
+
'version' => BAYEUX_VERSION,
|
95
|
+
'supportedConnectionTypes' => [@transport.connection_type]
|
97
96
|
|
98
97
|
}) do |response|
|
99
98
|
|
@@ -136,7 +135,7 @@ module Faye
|
|
136
135
|
|
137
136
|
info('Calling deferred actions for ?', @client_id)
|
138
137
|
set_deferred_status(:succeeded)
|
139
|
-
set_deferred_status(:
|
138
|
+
set_deferred_status(:unknown)
|
140
139
|
|
141
140
|
return unless @connect_request.nil?
|
142
141
|
@connect_request = true
|
@@ -275,6 +274,7 @@ module Faye
|
|
275
274
|
'channel' => channel,
|
276
275
|
'data' => data,
|
277
276
|
'clientId' => @client_id
|
277
|
+
|
278
278
|
}) do |response|
|
279
279
|
if response['successful']
|
280
280
|
publication.set_deferred_status(:succeeded)
|
@@ -287,20 +287,40 @@ module Faye
|
|
287
287
|
end
|
288
288
|
|
289
289
|
def receive_message(message)
|
290
|
-
|
290
|
+
id = message['id']
|
291
|
+
|
292
|
+
if message.has_key?('successful')
|
293
|
+
callback = @response_callbacks.delete(id)
|
294
|
+
end
|
295
|
+
|
296
|
+
pipe_through_extensions(:incoming, message, nil) do |message|
|
291
297
|
next unless message
|
292
298
|
|
293
299
|
handle_advice(message['advice']) if message['advice']
|
294
300
|
deliver_message(message)
|
295
301
|
|
296
|
-
|
302
|
+
callback.call(message) if callback
|
303
|
+
end
|
304
|
+
|
305
|
+
return if @transport_up == true
|
306
|
+
@transport_up = true
|
307
|
+
trigger('transport:up')
|
308
|
+
end
|
297
309
|
|
298
|
-
|
299
|
-
|
310
|
+
def message_error(messages, immediate = false)
|
311
|
+
messages.each do |message|
|
312
|
+
id = message['id']
|
300
313
|
|
301
|
-
|
302
|
-
|
314
|
+
if immediate
|
315
|
+
transport_send(message)
|
316
|
+
else
|
317
|
+
EventMachine.add_timer(@retry) { transport_send(message) }
|
318
|
+
end
|
303
319
|
end
|
320
|
+
|
321
|
+
return if immediate or @transport_up == false
|
322
|
+
@transport_up = false
|
323
|
+
trigger('transport:down')
|
304
324
|
end
|
305
325
|
|
306
326
|
private
|
@@ -309,35 +329,40 @@ module Faye
|
|
309
329
|
Transport.get(self, transport_types, @disabled) do |transport|
|
310
330
|
debug('Selected ? transport for ?', transport.connection_type, transport.endpoint)
|
311
331
|
|
312
|
-
|
313
|
-
@transport.
|
314
|
-
@transport.headers = @headers
|
315
|
-
|
316
|
-
transport.bind :down do
|
317
|
-
if @transport_up.nil? or @transport_up
|
318
|
-
@transport_up = false
|
319
|
-
trigger('transport:down')
|
320
|
-
end
|
321
|
-
end
|
332
|
+
next if transport == @transport
|
333
|
+
@transport.close if @transport
|
322
334
|
|
323
|
-
transport
|
324
|
-
if @transport_up.nil? or not @transport_up
|
325
|
-
@transport_up = true
|
326
|
-
trigger('transport:up')
|
327
|
-
end
|
328
|
-
end
|
335
|
+
@transport = transport
|
329
336
|
end
|
330
337
|
end
|
331
338
|
|
332
339
|
def send(message, &callback)
|
340
|
+
return unless @transport
|
333
341
|
message['id'] = generate_message_id
|
334
|
-
@response_callbacks[message['id']] = callback if callback
|
335
342
|
|
336
|
-
pipe_through_extensions(:outgoing, message) do |message|
|
337
|
-
|
343
|
+
pipe_through_extensions(:outgoing, message, nil) do |message|
|
344
|
+
next unless message
|
345
|
+
@response_callbacks[message['id']] = callback if callback
|
346
|
+
transport_send(message)
|
338
347
|
end
|
339
348
|
end
|
340
349
|
|
350
|
+
def transport_send(message)
|
351
|
+
return unless @transport
|
352
|
+
|
353
|
+
timeout = [nil, 0].include?(@advice['timeout']) ?
|
354
|
+
1.2 * @retry :
|
355
|
+
1.2 * @advice['timeout'] / 1000.0
|
356
|
+
|
357
|
+
envelope = Envelope.new(message, timeout)
|
358
|
+
|
359
|
+
envelope.errback do |immediate|
|
360
|
+
message_error([message], immediate)
|
361
|
+
end
|
362
|
+
|
363
|
+
@transport.send(envelope)
|
364
|
+
end
|
365
|
+
|
341
366
|
def generate_message_id
|
342
367
|
@message_id += 1
|
343
368
|
@message_id = 0 if @message_id >= 2**32
|
@@ -360,14 +385,11 @@ module Faye
|
|
360
385
|
@channels.distribute_message(message)
|
361
386
|
end
|
362
387
|
|
363
|
-
def teardown_connection
|
364
|
-
return unless @connect_request
|
365
|
-
@connect_request = nil
|
366
|
-
info('Closed connection for ?', @client_id)
|
367
|
-
end
|
368
|
-
|
369
388
|
def cycle_connection
|
370
|
-
|
389
|
+
if @connect_request
|
390
|
+
@connect_request = nil
|
391
|
+
info('Closed connection for ?', @client_id)
|
392
|
+
end
|
371
393
|
EventMachine.add_timer(@advice['interval'] / 1000.0) { connect }
|
372
394
|
end
|
373
395
|
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Faye
|
2
|
+
class Envelope
|
3
|
+
|
4
|
+
include Deferrable
|
5
|
+
attr_reader :id, :message
|
6
|
+
|
7
|
+
def initialize(message, timeout = nil)
|
8
|
+
@id = message['id']
|
9
|
+
@message = message
|
10
|
+
|
11
|
+
self.timeout(timeout, false) if timeout
|
12
|
+
end
|
13
|
+
|
14
|
+
def eql?(other)
|
15
|
+
Envelope === other and @id == other.id
|
16
|
+
end
|
17
|
+
|
18
|
+
def hash
|
19
|
+
@id.hash
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
@@ -17,7 +17,7 @@ module Faye
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
def pipe_through_extensions(stage, message, &callback)
|
20
|
+
def pipe_through_extensions(stage, message, env, &callback)
|
21
21
|
debug 'Passing through ? extensions: ?', stage, message
|
22
22
|
|
23
23
|
return callback.call(message) unless @extensions
|
@@ -29,10 +29,13 @@ module Faye
|
|
29
29
|
extension = extensions.shift
|
30
30
|
next callback.call(message) unless extension
|
31
31
|
|
32
|
-
|
33
|
-
|
32
|
+
next pipe.call(message) unless extension.respond_to?(stage)
|
33
|
+
|
34
|
+
arity = extension.method(stage).arity
|
35
|
+
if arity >= 3
|
36
|
+
extension.__send__(stage, message, env, pipe)
|
34
37
|
else
|
35
|
-
|
38
|
+
extension.__send__(stage, message, pipe)
|
36
39
|
end
|
37
40
|
end
|
38
41
|
pipe.call(message)
|
data/lib/faye/protocol/server.rb
CHANGED
@@ -19,21 +19,17 @@ module Faye
|
|
19
19
|
info 'Created new server: ?', @options
|
20
20
|
end
|
21
21
|
|
22
|
-
def
|
23
|
-
client_id
|
24
|
-
|
25
|
-
@engine.flush(client_id) if client_id
|
26
|
-
end
|
27
|
-
|
28
|
-
def open_socket(client_id, socket)
|
29
|
-
@engine.open_socket(client_id, Socket.new(self, socket))
|
22
|
+
def open_socket(client_id, socket, env)
|
23
|
+
return unless client_id and socket
|
24
|
+
@engine.open_socket(client_id, Socket.new(self, socket, env))
|
30
25
|
end
|
31
26
|
|
32
27
|
def close_socket(client_id)
|
33
28
|
@engine.flush(client_id)
|
34
29
|
end
|
35
30
|
|
36
|
-
def process(messages,
|
31
|
+
def process(messages, env, &callback)
|
32
|
+
local = env.nil?
|
37
33
|
messages = [messages].flatten
|
38
34
|
info 'Processing messages: ? (local: ?)', messages, local
|
39
35
|
|
@@ -54,7 +50,7 @@ module Faye
|
|
54
50
|
|
55
51
|
replies.each_with_index do |reply, i|
|
56
52
|
debug 'Processing reply: ?', reply
|
57
|
-
pipe_through_extensions(:outgoing, reply) do |message|
|
53
|
+
pipe_through_extensions(:outgoing, reply, env) do |message|
|
58
54
|
replies[i] = message
|
59
55
|
extended += 1
|
60
56
|
gather_replies.call(replies) if extended == expected
|
@@ -63,7 +59,7 @@ module Faye
|
|
63
59
|
end
|
64
60
|
|
65
61
|
messages.each do |message|
|
66
|
-
pipe_through_extensions(:incoming, message) do |piped_message|
|
62
|
+
pipe_through_extensions(:incoming, message, env) do |piped_message|
|
67
63
|
handle(piped_message, local, &handle_reply)
|
68
64
|
end
|
69
65
|
end
|
@@ -94,6 +90,7 @@ module Faye
|
|
94
90
|
error = Faye::Error.channel_invalid(channel_name)
|
95
91
|
end
|
96
92
|
|
93
|
+
message.delete('clientId')
|
97
94
|
@engine.publish(message) unless error
|
98
95
|
|
99
96
|
response = make_response(message)
|
data/lib/faye/protocol/socket.rb
CHANGED
@@ -2,19 +2,21 @@ module Faye
|
|
2
2
|
class Server
|
3
3
|
|
4
4
|
class Socket
|
5
|
-
def initialize(server, socket)
|
5
|
+
def initialize(server, socket, env)
|
6
6
|
@server = server
|
7
7
|
@socket = socket
|
8
|
+
@env = env
|
8
9
|
end
|
9
10
|
|
10
11
|
def send(message)
|
11
|
-
@server.pipe_through_extensions(:outgoing, message) do |piped_message|
|
12
|
-
@socket.send(Faye.to_json([piped_message]))
|
12
|
+
@server.pipe_through_extensions(:outgoing, message, @env) do |piped_message|
|
13
|
+
@socket.send(Faye.to_json([piped_message])) if @socket
|
13
14
|
end
|
14
15
|
end
|
15
16
|
|
16
17
|
def close
|
17
|
-
@socket.close
|
18
|
+
@socket.close if @socket
|
19
|
+
@socket = nil
|
18
20
|
end
|
19
21
|
end
|
20
22
|
|
data/lib/faye/transport/http.rb
CHANGED
@@ -2,37 +2,38 @@ module Faye
|
|
2
2
|
|
3
3
|
class Transport::Http < Transport
|
4
4
|
def self.usable?(client, endpoint, &callback)
|
5
|
-
callback.call(endpoint
|
5
|
+
callback.call(URI === endpoint)
|
6
6
|
end
|
7
7
|
|
8
|
-
def
|
9
|
-
|
8
|
+
def encode(envelopes)
|
9
|
+
Faye.to_json(envelopes.map { |e| e.message })
|
10
|
+
end
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
params = build_params(
|
12
|
+
def request(envelopes)
|
13
|
+
content = encode(envelopes)
|
14
|
+
params = build_params(@endpoint, content)
|
14
15
|
request = create_request(params)
|
15
16
|
|
16
17
|
request.callback do
|
17
|
-
handle_response(request.response,
|
18
|
-
store_cookies(
|
18
|
+
handle_response(request.response, envelopes)
|
19
|
+
store_cookies(request.response_header['SET_COOKIE'])
|
19
20
|
end
|
21
|
+
|
20
22
|
request.errback do
|
21
|
-
|
22
|
-
trigger(:down)
|
23
|
+
handle_error(envelopes)
|
23
24
|
end
|
24
25
|
end
|
25
26
|
|
26
27
|
private
|
27
28
|
|
28
|
-
def build_params(uri, content
|
29
|
+
def build_params(uri, content)
|
29
30
|
{
|
30
31
|
:head => {
|
31
32
|
'Content-Length' => content.bytesize,
|
32
33
|
'Content-Type' => 'application/json',
|
33
|
-
'Cookie' =>
|
34
|
+
'Cookie' => get_cookies,
|
34
35
|
'Host' => uri.host
|
35
|
-
}.merge(@headers),
|
36
|
+
}.merge(@client.headers),
|
36
37
|
|
37
38
|
:body => content,
|
38
39
|
:timeout => -1 # for em-http-request < 1.0
|
@@ -45,28 +46,20 @@ module Faye
|
|
45
46
|
options = { # for em-http-request >= 1.0
|
46
47
|
:inactivity_timeout => 0 # connection inactivity (post-setup) timeout (0 = disable timeout)
|
47
48
|
}
|
48
|
-
EventMachine::HttpRequest.new(@endpoint, options)
|
49
|
+
EventMachine::HttpRequest.new(@endpoint.to_s, options)
|
49
50
|
else
|
50
|
-
EventMachine::HttpRequest.new(@endpoint)
|
51
|
+
EventMachine::HttpRequest.new(@endpoint.to_s)
|
51
52
|
end
|
52
53
|
|
53
54
|
client.post(params)
|
54
55
|
end
|
55
56
|
|
56
|
-
def handle_response(response,
|
57
|
-
message =
|
57
|
+
def handle_response(response, envelopes)
|
58
|
+
message = MultiJson.load(response) rescue nil
|
58
59
|
if message
|
59
|
-
receive(message)
|
60
|
-
trigger(:up)
|
60
|
+
receive(envelopes, message)
|
61
61
|
else
|
62
|
-
|
63
|
-
trigger(:down)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def store_cookies(cookies)
|
68
|
-
cookies.each do |cookie|
|
69
|
-
@cookies.set_cookie(@endpoint, cookie)
|
62
|
+
handle_error(messages)
|
70
63
|
end
|
71
64
|
end
|
72
65
|
end
|