faye 0.3.4 → 0.5.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 +13 -0
- data/Manifest.txt +16 -33
- data/README.txt +9 -274
- data/Rakefile +4 -4
- data/lib/faye-browser-min.js +1 -0
- data/lib/faye.rb +26 -9
- data/lib/faye/{rack_adapter.rb → adapters/rack_adapter.rb} +38 -25
- data/lib/faye/error.rb +0 -7
- data/lib/faye/{logging.rb → mixins/logging.rb} +0 -0
- data/lib/faye/mixins/publisher.rb +29 -0
- data/lib/faye/{timeouts.rb → mixins/timeouts.rb} +1 -0
- data/lib/faye/{transport.rb → network/transport.rb} +32 -43
- data/lib/faye/{channel.rb → protocol/channel.rb} +23 -3
- data/lib/faye/{client.rb → protocol/client.rb} +124 -90
- data/lib/faye/{connection.rb → protocol/connection.rb} +41 -23
- data/lib/faye/protocol/extensible.rb +47 -0
- data/lib/faye/{grammar.rb → protocol/grammar.rb} +0 -0
- data/lib/faye/{server.rb → protocol/server.rb} +98 -54
- data/lib/faye/protocol/subscription.rb +23 -0
- data/lib/faye/{namespace.rb → util/namespace.rb} +0 -0
- data/lib/faye/util/web_socket.rb +119 -0
- data/lib/thin_extensions.rb +86 -0
- data/test/scenario.rb +68 -14
- data/test/test_clients.rb +215 -2
- data/test/test_server.rb +10 -10
- metadata +102 -71
- data/Jakefile +0 -13
- data/build/faye-client-min.js +0 -1
- data/build/faye.js +0 -1488
- data/examples/README.rdoc +0 -41
- data/examples/node/app.js +0 -26
- data/examples/node/client.js +0 -23
- data/examples/node/faye-client-min.js +0 -1
- data/examples/node/faye.js +0 -1488
- data/examples/rack/app.rb +0 -16
- data/examples/rack/client.rb +0 -25
- data/examples/rack/config.ru +0 -8
- data/examples/shared/public/favicon.ico +0 -0
- data/examples/shared/public/index.html +0 -49
- data/examples/shared/public/jquery.js +0 -19
- data/examples/shared/public/mootools.js +0 -4329
- data/examples/shared/public/prototype.js +0 -4874
- data/examples/shared/public/robots.txt +0 -0
- data/examples/shared/public/soapbox.js +0 -100
- data/examples/shared/public/style.css +0 -43
- data/jake.yml +0 -40
- data/lib/faye-client-min.js +0 -1
- data/test/scenario.js +0 -138
- data/test/test_clients.js +0 -195
@@ -0,0 +1,86 @@
|
|
1
|
+
# WebSocket extensions for Thin
|
2
|
+
# Taken from the Cramp project
|
3
|
+
# http://github.com/lifo/cramp
|
4
|
+
|
5
|
+
# Copyright (c) 2009-2010 Pratik Naik
|
6
|
+
#
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
8
|
+
# a copy of this software and associated documentation files (the
|
9
|
+
# "Software"), to deal in the Software without restriction, including
|
10
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
11
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
12
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
13
|
+
# the following conditions:
|
14
|
+
#
|
15
|
+
# The above copyright notice and this permission notice shall be
|
16
|
+
# included in all copies or substantial portions of the Software.
|
17
|
+
#
|
18
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
19
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
20
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
21
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
22
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
23
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
24
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
25
|
+
|
26
|
+
class Thin::Connection
|
27
|
+
def receive_data(data)
|
28
|
+
trace { data }
|
29
|
+
|
30
|
+
case @serving
|
31
|
+
when :websocket
|
32
|
+
callback = @request.env[Thin::Request::WEBSOCKET_RECEIVE_CALLBACK]
|
33
|
+
callback.call(data) if callback
|
34
|
+
else
|
35
|
+
if @request.parse(data)
|
36
|
+
if @request.websocket?
|
37
|
+
@response.persistent!
|
38
|
+
@response.websocket_upgrade_data = @request.websocket_upgrade_data
|
39
|
+
@serving = :websocket
|
40
|
+
end
|
41
|
+
|
42
|
+
process
|
43
|
+
end
|
44
|
+
end
|
45
|
+
rescue Thin::InvalidRequest => e
|
46
|
+
log "!! Invalid request"
|
47
|
+
log_error e
|
48
|
+
close_connection
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class Thin::Request
|
53
|
+
WEBSOCKET_RECEIVE_CALLBACK = 'websocket.receive_callback'.freeze
|
54
|
+
|
55
|
+
def websocket?
|
56
|
+
@env['HTTP_CONNECTION'] == 'Upgrade' && @env['HTTP_UPGRADE'] == 'WebSocket'
|
57
|
+
end
|
58
|
+
|
59
|
+
def websocket_url
|
60
|
+
@env['websocket.url'] = "ws://#{@env['HTTP_HOST']}#{@env['REQUEST_PATH']}"
|
61
|
+
end
|
62
|
+
|
63
|
+
def websocket_upgrade_data
|
64
|
+
upgrade = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n"
|
65
|
+
upgrade << "Upgrade: WebSocket\r\n"
|
66
|
+
upgrade << "Connection: Upgrade\r\n"
|
67
|
+
upgrade << "WebSocket-Origin: #{@env['HTTP_ORIGIN']}\r\n"
|
68
|
+
upgrade << "WebSocket-Location: #{websocket_url}\r\n\r\n"
|
69
|
+
upgrade
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
class Thin::Response
|
74
|
+
# Headers for sending Websocket upgrade
|
75
|
+
attr_accessor :websocket_upgrade_data
|
76
|
+
|
77
|
+
def each
|
78
|
+
websocket_upgrade_data ? yield(websocket_upgrade_data) : yield(head)
|
79
|
+
if @body.is_a?(String)
|
80
|
+
yield @body
|
81
|
+
else
|
82
|
+
@body.each { |chunk| yield chunk }
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
data/test/scenario.rb
CHANGED
@@ -59,18 +59,28 @@ module Scenario
|
|
59
59
|
def initialize
|
60
60
|
@clients = {}
|
61
61
|
@inbox = {}
|
62
|
+
@errors = {}
|
62
63
|
@pool = 0
|
63
64
|
end
|
65
|
+
|
66
|
+
def wait(time, &block)
|
67
|
+
EM.add_timer(time, &block)
|
68
|
+
end
|
64
69
|
|
65
70
|
def check_inbox(expected_inbox, &block)
|
66
71
|
assert_equal expected_inbox, @inbox
|
67
|
-
block
|
72
|
+
EM.next_tick(&block)
|
73
|
+
end
|
74
|
+
|
75
|
+
def check_errors(name, expected_errors, &block)
|
76
|
+
assert_equal expected_errors, @errors[name]
|
77
|
+
EM.next_tick(&block)
|
68
78
|
end
|
69
79
|
|
70
80
|
def server(port, &block)
|
71
|
-
@endpoint = "http://0.0.0.0:#{port}/
|
72
|
-
@
|
73
|
-
Rack::Handler.get('thin').run(@
|
81
|
+
@endpoint = "http://0.0.0.0:#{port}/bayeux"
|
82
|
+
@bayeux = Faye::RackAdapter.new(:mount => '/bayeux', :timeout => 30)
|
83
|
+
Rack::Handler.get('thin').run(@bayeux, :Port => port) do |server|
|
74
84
|
@server = server
|
75
85
|
EM.next_tick(&block)
|
76
86
|
end
|
@@ -81,25 +91,69 @@ module Scenario
|
|
81
91
|
end
|
82
92
|
|
83
93
|
def local_client(name, channels, &block)
|
84
|
-
setup_client(@
|
94
|
+
setup_client(@bayeux.get_client, name, channels, &block)
|
85
95
|
end
|
86
96
|
|
87
|
-
def
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
97
|
+
def extend_server(stage, extension, &block)
|
98
|
+
object = Object.new
|
99
|
+
def object.added
|
100
|
+
@active = true
|
101
|
+
end
|
102
|
+
(class << object; self; end).send(:define_method, stage) do |*args|
|
103
|
+
extension.call(*args) if @active
|
94
104
|
end
|
105
|
+
@bayeux.add_extension(object)
|
106
|
+
block.call
|
107
|
+
end
|
108
|
+
|
109
|
+
def extend_client(name, stage, extension, &block)
|
110
|
+
object = Object.new
|
111
|
+
(class << object; self; end).send(:define_method, stage, &extension)
|
112
|
+
@clients[name].add_extension(object)
|
113
|
+
block.call
|
114
|
+
end
|
115
|
+
|
116
|
+
def listen_for_errors(name, &block)
|
117
|
+
@errors[name] = []
|
118
|
+
errors = @errors
|
119
|
+
|
120
|
+
extend_client(name, :incoming, lambda { |message, callback|
|
121
|
+
if message['successful'] == false
|
122
|
+
errors[name] << message['error']
|
123
|
+
end
|
124
|
+
callback.call(message)
|
125
|
+
}, &block)
|
126
|
+
end
|
127
|
+
|
128
|
+
def setup_client(client, name, channels, &block)
|
95
129
|
@clients[name] = client
|
96
130
|
@inbox[name] = {}
|
97
131
|
@pool += 1
|
132
|
+
|
133
|
+
channels.each { |channel| subscribe(name, channel) }
|
98
134
|
EM.add_timer(0.5 * channels.size, &block)
|
99
135
|
end
|
100
136
|
|
101
|
-
def
|
102
|
-
@clients[
|
137
|
+
def subscribe(name, channel, &block)
|
138
|
+
client = @clients[name]
|
139
|
+
|
140
|
+
@last_sub = client.subscribe(channel) do |message|
|
141
|
+
box = @inbox[name]
|
142
|
+
box[channel] ||= []
|
143
|
+
box[channel] << message
|
144
|
+
end
|
145
|
+
|
146
|
+
EM.add_timer(0.5, &block)
|
147
|
+
end
|
148
|
+
|
149
|
+
def cancel_last_subscription(&block)
|
150
|
+
@last_sub.cancel
|
151
|
+
EM.add_timer(0.5, &block)
|
152
|
+
end
|
153
|
+
|
154
|
+
def publish(from, channel, messages, &block)
|
155
|
+
messages = [messages].flatten
|
156
|
+
messages.each { |msg| @clients[from].publish(channel, msg) }
|
103
157
|
EM.add_timer(2, &block)
|
104
158
|
end
|
105
159
|
|
data/test/test_clients.rb
CHANGED
@@ -6,6 +6,157 @@ class TestClients < Test::Unit::TestCase
|
|
6
6
|
include Faye
|
7
7
|
include Scenario
|
8
8
|
|
9
|
+
scenario "Client modifies incoming messages" do
|
10
|
+
server 8000
|
11
|
+
http_client :A, ['/channels/a']
|
12
|
+
http_client :B, ['/channels/b']
|
13
|
+
|
14
|
+
extend_client :A, :incoming, lambda { |message, callback|
|
15
|
+
if message['data']
|
16
|
+
message['data']['modified'] = 'hi'
|
17
|
+
end
|
18
|
+
callback.call(message)
|
19
|
+
}
|
20
|
+
|
21
|
+
publish :B, '/channels/a', 'welcome' => 'message'
|
22
|
+
check_inbox(
|
23
|
+
:A => {
|
24
|
+
'/channels/a' => ['welcome' => 'message', 'modified' => 'hi']
|
25
|
+
},
|
26
|
+
:B => {}
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
scenario "Client blocks incoming messages" do
|
31
|
+
server 8000
|
32
|
+
http_client :A, ['/channels/a']
|
33
|
+
http_client :B, ['/channels/b']
|
34
|
+
|
35
|
+
extend_client :A, :incoming, lambda { |message, callback|
|
36
|
+
callback.call(nil)
|
37
|
+
}
|
38
|
+
|
39
|
+
publish :B, '/channels/a', 'welcome' => 'message'
|
40
|
+
check_inbox( :A => {}, :B => {} )
|
41
|
+
end
|
42
|
+
|
43
|
+
scenario "Server requires authentication" do
|
44
|
+
server 8000
|
45
|
+
http_client :A, ['/channels/a']
|
46
|
+
http_client :B, ['/channels/b']
|
47
|
+
|
48
|
+
extend_server :incoming, lambda { |message, callback|
|
49
|
+
if message['ext'] and message['ext']['password']
|
50
|
+
callback.call(message)
|
51
|
+
end
|
52
|
+
}
|
53
|
+
|
54
|
+
extend_client :B, :outgoing, lambda { |message, callback|
|
55
|
+
message['ext'] = {'password' => true}
|
56
|
+
callback.call(message)
|
57
|
+
}
|
58
|
+
|
59
|
+
publish :A, '/channels/b', 'message_for' => 'B'
|
60
|
+
check_inbox( :A => {}, :B => {} )
|
61
|
+
|
62
|
+
publish :B, '/channels/a', 'message_for' => 'A'
|
63
|
+
check_inbox(
|
64
|
+
:A => {
|
65
|
+
'/channels/a' => ['message_for' => 'A']
|
66
|
+
},
|
67
|
+
:B => {}
|
68
|
+
)
|
69
|
+
end
|
70
|
+
|
71
|
+
scenario "Server blocks a message by setting an error" do
|
72
|
+
server 8000
|
73
|
+
http_client :A, ['/channels/a']
|
74
|
+
http_client :B, ['/channels/b']
|
75
|
+
|
76
|
+
extend_server :incoming, lambda { |message, callback|
|
77
|
+
if message['data']
|
78
|
+
message['error'] = Faye::Error.ext_mismatch
|
79
|
+
end
|
80
|
+
callback.call(message)
|
81
|
+
}
|
82
|
+
|
83
|
+
listen_for_errors :A
|
84
|
+
|
85
|
+
publish :A, '/channels/b', 'message_for' => 'B'
|
86
|
+
check_inbox( :A => {}, :B => {} )
|
87
|
+
check_errors :A, ['302::Extension mismatch']
|
88
|
+
end
|
89
|
+
|
90
|
+
scenario "Server modifies outgoing message" do
|
91
|
+
server 8000
|
92
|
+
http_client :A, []
|
93
|
+
http_client :B, ['/channels/b']
|
94
|
+
|
95
|
+
extend_server :outgoing, lambda { |message, callback|
|
96
|
+
message['data']['addition'] = 56 if message['data']
|
97
|
+
callback.call(message)
|
98
|
+
}
|
99
|
+
|
100
|
+
publish :A, '/channels/b', 'message_for' => 'B'
|
101
|
+
check_inbox(
|
102
|
+
:A => {},
|
103
|
+
:B => {
|
104
|
+
'/channels/b' => ['message_for' => 'B', 'addition' => 56]
|
105
|
+
}
|
106
|
+
)
|
107
|
+
end
|
108
|
+
|
109
|
+
[:incoming, :outgoing].each do |direction|
|
110
|
+
scenario "Server delays #{ direction } message" do
|
111
|
+
server 8000
|
112
|
+
http_client :A, []
|
113
|
+
http_client :B, ['/channels/b']
|
114
|
+
|
115
|
+
extend_server direction, lambda { |message, callback|
|
116
|
+
timeout = message['data'] ? 5 : 0
|
117
|
+
EM.add_timer(timeout) { callback.call(message) }
|
118
|
+
}
|
119
|
+
|
120
|
+
publish :A, '/channels/b', 'message_for' => 'B'
|
121
|
+
check_inbox( :A => {}, :B => {} )
|
122
|
+
|
123
|
+
wait 3
|
124
|
+
check_inbox( :A => {}, :B => {} )
|
125
|
+
|
126
|
+
wait 1
|
127
|
+
|
128
|
+
check_inbox(
|
129
|
+
:A => {},
|
130
|
+
:B => {
|
131
|
+
'/channels/b' => ['message_for' => 'B']
|
132
|
+
}
|
133
|
+
)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
scenario "Server blocks outgoing message" do
|
138
|
+
server 8000
|
139
|
+
http_client :A, []
|
140
|
+
http_client :B, ['/channels/b']
|
141
|
+
|
142
|
+
extend_server :outgoing, lambda { |message, callback|
|
143
|
+
if !message['data'] or message['data']['deliver'] == 'yes'
|
144
|
+
callback.call(message)
|
145
|
+
else
|
146
|
+
callback.call(nil)
|
147
|
+
end
|
148
|
+
}
|
149
|
+
|
150
|
+
publish :A, '/channels/b', [{'deliver' => 'no'}, {'deliver' => 'yes'}]
|
151
|
+
|
152
|
+
check_inbox(
|
153
|
+
:A => {},
|
154
|
+
:B => {
|
155
|
+
'/channels/b' => ['deliver' => 'yes']
|
156
|
+
}
|
157
|
+
)
|
158
|
+
end
|
159
|
+
|
9
160
|
scenario "Two HTTP clients, no messages delivered" do
|
10
161
|
server 8000
|
11
162
|
http_client :A, ['/channels/a']
|
@@ -29,6 +180,40 @@ class TestClients < Test::Unit::TestCase
|
|
29
180
|
:B => {}
|
30
181
|
)
|
31
182
|
end
|
183
|
+
|
184
|
+
scenario "Two HTTP clients, two identical messages sent together" do
|
185
|
+
server 8000
|
186
|
+
http_client :A, ['/channels/a']
|
187
|
+
http_client :B, []
|
188
|
+
publish :B, '/channels/a', [{'hello' => 'world'}, {'hello' => 'world'}]
|
189
|
+
check_inbox(
|
190
|
+
:A => {
|
191
|
+
'/channels/a' => [{'hello' => 'world'}, {'hello' => 'world'}]
|
192
|
+
},
|
193
|
+
:B => {}
|
194
|
+
)
|
195
|
+
end
|
196
|
+
|
197
|
+
scenario "Two HTTP clients, two message deliveries" do
|
198
|
+
server 8000
|
199
|
+
http_client :A, ['/channels/a']
|
200
|
+
http_client :B, []
|
201
|
+
publish :B, '/channels/a', 'hello' => 'world'
|
202
|
+
check_inbox(
|
203
|
+
:A => {
|
204
|
+
'/channels/a' => ['hello' => 'world']
|
205
|
+
},
|
206
|
+
:B => {}
|
207
|
+
)
|
208
|
+
wait 1
|
209
|
+
publish :B, '/channels/a', 'hello' => 'world'
|
210
|
+
check_inbox(
|
211
|
+
:A => {
|
212
|
+
'/channels/a' => [{'hello' => 'world'}, {'hello' => 'world'}]
|
213
|
+
},
|
214
|
+
:B => {}
|
215
|
+
)
|
216
|
+
end
|
32
217
|
|
33
218
|
scenario "Two HTTP clients, multiple subscriptions" do
|
34
219
|
server 8000
|
@@ -44,6 +229,35 @@ class TestClients < Test::Unit::TestCase
|
|
44
229
|
)
|
45
230
|
end
|
46
231
|
|
232
|
+
scenario "Two HTTP clients, two subscriptions on the same channel" do
|
233
|
+
server 8000
|
234
|
+
http_client :A, ['/channels/a']
|
235
|
+
http_client :B, []
|
236
|
+
subscribe :A, '/channels/a'
|
237
|
+
publish :B, '/channels/a', 'hello' => 'world'
|
238
|
+
check_inbox(
|
239
|
+
:A => {
|
240
|
+
'/channels/a' => [{'hello' => 'world'}, {'hello' => 'world'}]
|
241
|
+
},
|
242
|
+
:B => {}
|
243
|
+
)
|
244
|
+
end
|
245
|
+
|
246
|
+
scenario "Two HTTP clients, two subscriptions and one unsubscription" do
|
247
|
+
server 8000
|
248
|
+
http_client :A, ['/channels/a']
|
249
|
+
http_client :B, []
|
250
|
+
subscribe :A, '/channels/a'
|
251
|
+
cancel_last_subscription
|
252
|
+
publish :B, '/channels/a', 'another' => 'message'
|
253
|
+
check_inbox(
|
254
|
+
:A => {
|
255
|
+
'/channels/a' => [{'another' => 'message'}]
|
256
|
+
},
|
257
|
+
:B => {}
|
258
|
+
)
|
259
|
+
end
|
260
|
+
|
47
261
|
scenario "Three HTTP clients, single receiver" do
|
48
262
|
server 8000
|
49
263
|
http_client :A, ['/channels/a']
|
@@ -145,8 +359,7 @@ class TestClients < Test::Unit::TestCase
|
|
145
359
|
:B => {},
|
146
360
|
:C => {
|
147
361
|
'/channels/name' => ['msg' => 'hey'],
|
148
|
-
'/channels/foo/**' => ['msg' => 'hey']
|
149
|
-
'/channels/name' => ['msg' => 'hey'],
|
362
|
+
'/channels/foo/**' => ['msg' => 'hey']
|
150
363
|
}
|
151
364
|
)
|
152
365
|
end
|
data/test/test_server.rb
CHANGED
@@ -30,7 +30,7 @@ class TestServer < Test::Unit::TestCase
|
|
30
30
|
# MUST
|
31
31
|
assert_equal '/meta/handshake', @r['channel']
|
32
32
|
assert_not_equal nil, @r['version']
|
33
|
-
assert_equal %w[long-polling callback-polling],
|
33
|
+
assert_equal %w[long-polling callback-polling websocket], @r['supportedConnectionTypes']
|
34
34
|
assert_match( /[a-z0-9]+/, @r['clientId'] )
|
35
35
|
assert_equal true, @r['successful']
|
36
36
|
# MAY
|
@@ -62,7 +62,7 @@ class TestServer < Test::Unit::TestCase
|
|
62
62
|
assert_equal '402:version:Missing required parameter', @r['error']
|
63
63
|
# MAY
|
64
64
|
assert_not_equal nil, @r['version']
|
65
|
-
assert_equal %w[long-polling callback-polling],
|
65
|
+
assert_equal %w[long-polling callback-polling websocket], @r['supportedConnectionTypes']
|
66
66
|
# MAY include advice, minimumVersion, ext, id
|
67
67
|
|
68
68
|
#================================================================
|
@@ -73,7 +73,7 @@ class TestServer < Test::Unit::TestCase
|
|
73
73
|
assert_equal false, @r['successful']
|
74
74
|
assert_equal '301:iframe,flash:Connection types not supported', @r['error']
|
75
75
|
# MAY
|
76
|
-
assert_equal %w[long-polling callback-polling],
|
76
|
+
assert_equal %w[long-polling callback-polling websocket], @r['supportedConnectionTypes']
|
77
77
|
assert_equal nil, @r['id']
|
78
78
|
|
79
79
|
#================================================================
|
@@ -84,7 +84,7 @@ class TestServer < Test::Unit::TestCase
|
|
84
84
|
assert_equal false, @r['successful']
|
85
85
|
assert_equal '402:supportedConnectionTypes:Missing required parameter', @r['error']
|
86
86
|
# MAY
|
87
|
-
assert_equal %w[long-polling callback-polling],
|
87
|
+
assert_equal %w[long-polling callback-polling websocket], @r['supportedConnectionTypes']
|
88
88
|
assert_equal 'foo', @r['id']
|
89
89
|
|
90
90
|
#================================================================
|
@@ -448,16 +448,16 @@ class TestServer < Test::Unit::TestCase
|
|
448
448
|
|
449
449
|
def test_advice
|
450
450
|
@server.send :handle, 'channel' => '/meta/subscribe', 'subscription' => '/foo', 'clientId' => 'fake' do |r|
|
451
|
-
assert_equal '401:fake:Unknown client', r['error']
|
452
|
-
assert_equal 'handshake', r['advice']['reconnect']
|
453
|
-
assert_equal 1000, r['advice']['interval']
|
451
|
+
assert_equal '401:fake:Unknown client', r.first['error']
|
452
|
+
assert_equal 'handshake', r.first['advice']['reconnect']
|
454
453
|
end
|
455
454
|
|
456
455
|
id = get_client_id
|
457
456
|
@server.send :handle, 'channel' => '/meta/subscribe', 'subscription' => '/foo', 'clientId' => id do |r|
|
458
|
-
assert_equal true, r['successful']
|
459
|
-
assert_equal 'retry', r['advice']['reconnect']
|
460
|
-
assert_equal
|
457
|
+
assert_equal true, r.first['successful']
|
458
|
+
assert_equal 'retry', r.first['advice']['reconnect']
|
459
|
+
assert_equal 0, r.first['advice']['interval']
|
460
|
+
assert_equal 60000, r.first['advice']['timeout']
|
461
461
|
end
|
462
462
|
end
|
463
463
|
end
|