wamp_client 0.1.4 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +34 -32
- data/lib/wamp/client/auth.rb +0 -27
- data/lib/wamp/client/check.rb +0 -27
- data/lib/wamp/client/connection.rb +40 -113
- data/lib/wamp/client/event.rb +78 -0
- data/lib/wamp/client/manager/base.rb +39 -0
- data/lib/wamp/client/manager/base_multiple.rb +37 -0
- data/lib/wamp/client/manager/establish.rb +168 -0
- data/lib/wamp/client/manager/registration.rb +183 -0
- data/lib/wamp/client/manager/require.rb +3 -0
- data/lib/wamp/client/manager/subscription.rb +55 -0
- data/lib/wamp/client/request/base.rb +125 -0
- data/lib/wamp/client/request/call.rb +111 -0
- data/lib/wamp/client/request/publish.rb +72 -0
- data/lib/wamp/client/request/register.rb +79 -0
- data/lib/wamp/client/request/require.rb +6 -0
- data/lib/wamp/client/request/subscribe.rb +78 -0
- data/lib/wamp/client/request/unregister.rb +71 -0
- data/lib/wamp/client/request/unsubscribe.rb +72 -0
- data/lib/wamp/client/response.rb +136 -0
- data/lib/wamp/client/serializer.rb +0 -29
- data/lib/wamp/client/session.rb +172 -839
- data/lib/wamp/client/transport/base.rb +4 -77
- data/lib/wamp/client/transport/event_machine_base.rb +0 -27
- data/lib/wamp/client/transport/faye_web_socket.rb +4 -31
- data/lib/wamp/client/transport/web_socket_event_machine.rb +3 -30
- data/lib/wamp/client/version.rb +1 -28
- data/lib/wamp/client.rb +1 -28
- data/spec/spec_helper.rb +3 -137
- data/spec/support/faye_web_socket_client_stub.rb +43 -0
- data/spec/support/test_transport.rb +50 -0
- data/spec/support/web_socket_event_machine_client_stub.rb +39 -0
- data/spec/wamp/client/connection_spec.rb +4 -4
- data/spec/wamp/client/session_spec.rb +135 -135
- data/spec/wamp/client/transport_spec.rb +2 -2
- data/wamp_client.gemspec +10 -9
- metadata +59 -38
- data/lib/wamp/client/defer.rb +0 -70
data/lib/wamp/client/session.rb
CHANGED
@@ -1,211 +1,52 @@
|
|
1
|
-
=begin
|
2
|
-
|
3
|
-
Copyright (c) 2018 Eric Chapman
|
4
|
-
|
5
|
-
MIT License
|
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
|
-
=end
|
27
|
-
|
28
1
|
require 'wamp/client/transport/base'
|
29
2
|
require 'wamp/client/message'
|
30
3
|
require 'wamp/client/check'
|
31
4
|
require 'wamp/client/version'
|
5
|
+
require 'wamp/client/event'
|
6
|
+
require 'wamp/client/request/require'
|
7
|
+
require 'wamp/client/manager/require'
|
32
8
|
|
33
9
|
module Wamp
|
34
10
|
module Client
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
call_canceling: true,
|
41
|
-
progressive_call_results: true
|
42
|
-
}
|
43
|
-
},
|
44
|
-
callee: {
|
45
|
-
features: {
|
46
|
-
caller_identification: true,
|
47
|
-
##call_trustlevels: true,
|
48
|
-
pattern_based_registration: true,
|
49
|
-
shared_registration: true,
|
50
|
-
##call_timeout: true,
|
51
|
-
call_canceling: true,
|
52
|
-
progressive_call_results: true,
|
53
|
-
registration_revocation: true
|
54
|
-
}
|
55
|
-
},
|
56
|
-
publisher: {
|
57
|
-
features: {
|
58
|
-
publisher_identification: true,
|
59
|
-
subscriber_blackwhite_listing: true,
|
60
|
-
publisher_exclusion: true
|
61
|
-
}
|
62
|
-
},
|
63
|
-
subscriber: {
|
64
|
-
features: {
|
65
|
-
publisher_identification: true,
|
66
|
-
##publication_trustlevels: true,
|
67
|
-
pattern_based_subscription: true,
|
68
|
-
subscription_revocation: true
|
69
|
-
##event_history: true,
|
70
|
-
}
|
71
|
-
}
|
11
|
+
|
12
|
+
CLOSED_SESSION_METHOD_LOOKUP = {
|
13
|
+
Message::Types::WELCOME => -> s, m { s.establish.welcome(m) },
|
14
|
+
Message::Types::CHALLENGE => -> s, m { s.establish.challenge(m) },
|
15
|
+
Message::Types::ABORT => -> s, m { s.establish.abort(m) },
|
72
16
|
}
|
73
17
|
|
74
|
-
|
18
|
+
OPEN_SESSION_METHOD_LOOKUP = {
|
19
|
+
# Establish Response
|
20
|
+
Message::Types::GOODBYE => -> s, m { s.establish.goodbye(m) },
|
21
|
+
|
75
22
|
# Error Responses
|
76
|
-
Message::Types::SUBSCRIBE => -> s,m { s.
|
77
|
-
Message::Types::UNSUBSCRIBE => -> s,m { s.
|
78
|
-
Message::Types::PUBLISH => -> s,m { s.
|
79
|
-
Message::Types::REGISTER => -> s,m { s.
|
80
|
-
Message::Types::UNREGISTER => -> s,m { s.
|
81
|
-
Message::Types::CALL => -> s,m { s.
|
23
|
+
Message::Types::SUBSCRIBE => -> s, m { s.request[:subscribe].error(m) },
|
24
|
+
Message::Types::UNSUBSCRIBE => -> s, m { s.request[:unsubscribe].error(m) },
|
25
|
+
Message::Types::PUBLISH => -> s, m { s.request[:publish].error(m) },
|
26
|
+
Message::Types::REGISTER => -> s, m { s.request[:register].error(m) },
|
27
|
+
Message::Types::UNREGISTER => -> s, m { s.request[:unregister].error(m) },
|
28
|
+
Message::Types::CALL => -> s, m { s.request[:call].error(m) },
|
82
29
|
|
83
30
|
# Result Responses
|
84
|
-
Message::Types::SUBSCRIBED => -> s,m { s.
|
85
|
-
Message::Types::UNSUBSCRIBED => -> s,m { s.
|
86
|
-
Message::Types::PUBLISHED => -> s,m { s.
|
87
|
-
Message::Types::EVENT => -> s,m { s.
|
88
|
-
Message::Types::REGISTERED => -> s,m { s.
|
89
|
-
Message::Types::UNREGISTERED => -> s,m { s.
|
90
|
-
Message::Types::INVOCATION => -> s,m { s.
|
91
|
-
Message::Types::INTERRUPT => -> s,m { s.
|
92
|
-
Message::Types::RESULT => -> s,m { s.
|
31
|
+
Message::Types::SUBSCRIBED => -> s, m { s.request[:subscribe].success(m) },
|
32
|
+
Message::Types::UNSUBSCRIBED => -> s, m { s.request[:unsubscribe].success(m) },
|
33
|
+
Message::Types::PUBLISHED => -> s, m { s.request[:publish].success(m) },
|
34
|
+
Message::Types::EVENT => -> s, m { s.subscription.event(m) },
|
35
|
+
Message::Types::REGISTERED => -> s, m { s.request[:register].success(m) },
|
36
|
+
Message::Types::UNREGISTERED => -> s, m { s.request[:unregister].success(m) },
|
37
|
+
Message::Types::INVOCATION => -> s, m { s.registration.invoke(m) },
|
38
|
+
Message::Types::INTERRUPT => -> s, m { s.registration.interrupt(m) },
|
39
|
+
Message::Types::RESULT => -> s, m { s.request[:call].success(m) },
|
93
40
|
}
|
94
41
|
|
95
|
-
class CallResult
|
96
|
-
attr_accessor :args, :kwargs
|
97
|
-
|
98
|
-
def initialize(args=nil, kwargs=nil)
|
99
|
-
self.args = args || []
|
100
|
-
self.kwargs = kwargs || {}
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
class CallError < Exception
|
105
|
-
attr_accessor :error, :args, :kwargs
|
106
|
-
|
107
|
-
def initialize(error, args=nil, kwargs=nil)
|
108
|
-
self.error = error
|
109
|
-
self.args = args || []
|
110
|
-
self.kwargs = kwargs || {}
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
class Subscription
|
115
|
-
attr_accessor :topic, :handler, :options, :session, :id
|
116
|
-
|
117
|
-
def initialize(topic, handler, options, session, id)
|
118
|
-
self.topic = topic
|
119
|
-
self.handler = handler
|
120
|
-
self.options = options
|
121
|
-
self.session = session
|
122
|
-
self.id = id
|
123
|
-
end
|
124
|
-
|
125
|
-
def unsubscribe
|
126
|
-
self.session.unsubscribe(self)
|
127
|
-
end
|
128
|
-
|
129
|
-
end
|
130
|
-
|
131
|
-
class Registration
|
132
|
-
attr_accessor :procedure, :handler, :i_handler, :options, :session, :id
|
133
|
-
|
134
|
-
def initialize(procedure, handler, options, i_handler, session, id)
|
135
|
-
self.procedure = procedure
|
136
|
-
self.handler = handler
|
137
|
-
self.options = options
|
138
|
-
self.i_handler = i_handler
|
139
|
-
self.session = session
|
140
|
-
self.id = id
|
141
|
-
end
|
142
|
-
|
143
|
-
def unregister
|
144
|
-
self.session.unregister(self)
|
145
|
-
end
|
146
|
-
|
147
|
-
end
|
148
|
-
|
149
|
-
class Call
|
150
|
-
attr_accessor :session, :id
|
151
|
-
|
152
|
-
def initialize(session, id)
|
153
|
-
self.session = session
|
154
|
-
self.id = id
|
155
|
-
end
|
156
|
-
|
157
|
-
def cancel(mode='skip')
|
158
|
-
self.session.cancel(self, mode)
|
159
|
-
end
|
160
|
-
|
161
|
-
end
|
162
|
-
|
163
42
|
class Session
|
164
43
|
include Check
|
44
|
+
include Event
|
165
45
|
|
166
|
-
|
167
|
-
|
168
|
-
@on_join
|
169
|
-
def on_join(&on_join)
|
170
|
-
@on_join = on_join
|
171
|
-
end
|
172
|
-
|
173
|
-
# on_leave callback is called when the session leaves the router. It has the following attributes
|
174
|
-
# @param reason [String] The reason the session left the router
|
175
|
-
# @param details [Hash] Object containing information about the left session
|
176
|
-
@on_leave
|
177
|
-
def on_leave(&on_leave)
|
178
|
-
@on_leave = on_leave
|
179
|
-
end
|
180
|
-
|
181
|
-
# on_challenge callback is called when an authentication challenge is received from the router. It has the
|
182
|
-
# following attributes
|
183
|
-
# @param authmethod [String] The type of auth being requested
|
184
|
-
# @param extra [Hash] Hash containing additional information
|
185
|
-
# @return signature, extras
|
186
|
-
@on_challenge
|
187
|
-
def on_challenge(&on_challenge)
|
188
|
-
@on_challenge = on_challenge
|
189
|
-
end
|
190
|
-
|
191
|
-
# Simple setter for callbacks
|
192
|
-
def on(event, &callback)
|
193
|
-
case event
|
194
|
-
when :join
|
195
|
-
self.on_join(&callback)
|
196
|
-
when :challenge
|
197
|
-
self.on_challenge(&callback)
|
198
|
-
when :leave
|
199
|
-
self.on_leave(&callback)
|
200
|
-
else
|
201
|
-
raise RuntimeError, "Unknown on(event) '#{event}'"
|
202
|
-
end
|
203
|
-
end
|
46
|
+
attr_accessor :transport, :options, :request, :callback,
|
47
|
+
:subscription, :registration, :establish
|
204
48
|
|
205
|
-
|
206
|
-
|
207
|
-
# Private attributes
|
208
|
-
attr_accessor :_goodbye_sent, :_requests, :_subscriptions, :_registrations, :_defers
|
49
|
+
create_event [:join, :challenge, :leave]
|
209
50
|
|
210
51
|
# Constructor
|
211
52
|
# @param transport [Transport::Base] The transport that the session will use
|
@@ -215,697 +56,187 @@ module Wamp
|
|
215
56
|
def initialize(transport, options={})
|
216
57
|
|
217
58
|
# Parameters
|
218
|
-
self.id = nil
|
219
|
-
self.realm = nil
|
220
59
|
self.options = options || {}
|
221
60
|
|
61
|
+
# Log the event
|
62
|
+
logger.info("#{self.class.name} created with options")
|
63
|
+
logger.info(" uri: #{options[:uri]}")
|
64
|
+
logger.info(" realm: #{options[:realm]}")
|
65
|
+
|
66
|
+
# Create the send message lambda for the request objects
|
67
|
+
send_message_lambda = -> m { send_message(m) }
|
68
|
+
|
222
69
|
# Outstanding Requests
|
223
|
-
self.
|
224
|
-
publish:
|
225
|
-
subscribe: {},
|
226
|
-
unsubscribe: {},
|
227
|
-
call:
|
228
|
-
register: {},
|
229
|
-
unregister: {}
|
70
|
+
self.request = {
|
71
|
+
publish: Request::Publish.new(self, send_message_lambda),
|
72
|
+
subscribe: Request::Subscribe.new(self, send_message_lambda) { |s_id, s| self.subscription.add(s_id, s) },
|
73
|
+
unsubscribe: Request::Unsubscribe.new(self, send_message_lambda) { |s_id| self.subscription.remove(s_id) },
|
74
|
+
call: Request::Call.new(self, send_message_lambda),
|
75
|
+
register: Request::Register.new(self, send_message_lambda) { |r_id, r| self.registration.add(r_id, r) },
|
76
|
+
unregister: Request::Unregister.new(self, send_message_lambda) { |r_id| self.registration.remove(r_id) },
|
230
77
|
}
|
231
78
|
|
232
79
|
# Init Subs and Regs in place
|
233
|
-
self.
|
234
|
-
self.
|
235
|
-
self.
|
80
|
+
self.subscription = Manager::Subscription.new(self, send_message_lambda)
|
81
|
+
self.registration = Manager::Registration.new(self, send_message_lambda)
|
82
|
+
self.establish = Manager::Establish.new(self, send_message_lambda)
|
83
|
+
|
84
|
+
# Setup session callbacks
|
85
|
+
self.callback = {}
|
236
86
|
|
237
87
|
# Setup Transport
|
238
88
|
self.transport = transport
|
239
|
-
self.transport.
|
240
|
-
|
89
|
+
self.transport.on :message do |msg|
|
90
|
+
receive_message(msg)
|
241
91
|
end
|
242
92
|
|
243
|
-
# Other parameters
|
244
|
-
self._goodbye_sent = false
|
245
|
-
|
246
|
-
# Setup session callbacks
|
247
|
-
@on_join = nil
|
248
|
-
@on_leave = nil
|
249
|
-
@on_challenge = nil
|
250
|
-
|
251
93
|
end
|
252
94
|
|
253
95
|
# Returns 'true' if the session is open
|
96
|
+
#
|
254
97
|
def is_open?
|
255
|
-
|
98
|
+
self.establish.is_open?
|
99
|
+
end
|
100
|
+
|
101
|
+
# Returns the ID of the session
|
102
|
+
#
|
103
|
+
def id
|
104
|
+
self.establish.id
|
105
|
+
end
|
106
|
+
|
107
|
+
# Returns the realm of the session
|
108
|
+
#
|
109
|
+
def realm
|
110
|
+
self.establish.realm
|
256
111
|
end
|
257
112
|
|
258
113
|
# Joins the WAMP Router
|
114
|
+
#
|
259
115
|
# @param realm [String] The name of the realm
|
260
116
|
def join(realm)
|
261
|
-
|
262
|
-
raise RuntimeError, "Session must be closed to call 'join'"
|
263
|
-
end
|
117
|
+
check_closed
|
264
118
|
|
119
|
+
# Check params
|
265
120
|
self.class.check_uri('realm', realm)
|
266
121
|
|
267
|
-
|
268
|
-
|
269
|
-
details = {}
|
270
|
-
details[:roles] = WAMP_FEATURES
|
271
|
-
details[:agent] = "Ruby-Wamp::Client-#{VERSION}"
|
272
|
-
details[:authid] = self.options[:authid] if self.options[:authid]
|
273
|
-
details[:authmethods] = self.options[:authmethods] if self.options[:authmethods]
|
274
|
-
|
275
|
-
# Send Hello message
|
276
|
-
hello = Message::Hello.new(realm, details)
|
277
|
-
self._send_message(hello)
|
122
|
+
# Attempt to join
|
123
|
+
self.establish.join(realm)
|
278
124
|
end
|
279
125
|
|
280
126
|
# Leaves the WAMP Router
|
127
|
+
#
|
281
128
|
# @param reason [String] URI signalling the reason for leaving
|
282
129
|
def leave(reason='wamp.close.normal', message='user initiated')
|
283
|
-
|
284
|
-
raise RuntimeError, "Session must be opened to call 'leave'"
|
285
|
-
end
|
130
|
+
check_open
|
286
131
|
|
132
|
+
# Check params
|
287
133
|
self.class.check_uri('reason', reason, true)
|
288
134
|
self.class.check_string('message', message, true)
|
289
135
|
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
# Send Goodbye message
|
294
|
-
goodbye = Message::Goodbye.new(details, reason)
|
295
|
-
self._send_message(goodbye)
|
296
|
-
self._goodbye_sent = true
|
297
|
-
end
|
298
|
-
|
299
|
-
# Generates an ID according to the specification (Section 5.1.2)
|
300
|
-
def _generate_id
|
301
|
-
rand(0..9007199254740992)
|
136
|
+
# Leave the session
|
137
|
+
self.establish.leave(reason, message)
|
302
138
|
end
|
303
139
|
|
304
|
-
# Converts and error message to a hash
|
305
|
-
# @param msg [Message::Error]
|
306
|
-
def _error_to_hash(msg)
|
307
|
-
{
|
308
|
-
error: msg.error,
|
309
|
-
args: msg.arguments,
|
310
|
-
kwargs: msg.argumentskw
|
311
|
-
}
|
312
|
-
end
|
313
|
-
|
314
|
-
# Sends a message
|
315
|
-
# @param msg [Message::Base]
|
316
|
-
def _send_message(msg)
|
317
|
-
# Log the message
|
318
|
-
logger.debug("#{self.class.name} TX: #{msg.to_s}")
|
319
|
-
|
320
|
-
# Send it to the transport
|
321
|
-
self.transport.send_message(msg.payload)
|
322
|
-
end
|
323
|
-
|
324
|
-
# Processes received messages
|
325
|
-
# @param msg [Array]
|
326
|
-
def _receive_message(msg)
|
327
|
-
|
328
|
-
# Print the raw message
|
329
|
-
logger.debug("#{self.class.name} RX(raw): #{msg.to_s}")
|
330
|
-
|
331
|
-
# Parse the WAMP message
|
332
|
-
message = Message.parse(msg)
|
333
|
-
|
334
|
-
# Print the parsed WAMP message
|
335
|
-
logger.debug("#{self.class.name} RX: #{message.to_s}")
|
336
|
-
|
337
|
-
# WAMP Session is not open
|
338
|
-
if self.id.nil?
|
339
|
-
|
340
|
-
# Parse the welcome message
|
341
|
-
if message.is_a? Message::Welcome
|
342
|
-
# Get the session ID
|
343
|
-
self.id = message.session
|
344
|
-
|
345
|
-
# Log joining the session
|
346
|
-
logger.info("#{self.class.name} joined session with realm '#{message.details[:realm]}'")
|
347
|
-
|
348
|
-
# Call the callback if it is set
|
349
|
-
@on_join.call(message.details) unless @on_join.nil?
|
350
|
-
elsif message.is_a? Message::Challenge
|
351
|
-
# Log challenge received
|
352
|
-
logger.debug("#{self.class.name} auth challenge '#{message.authmethod}', extra: #{message.extra}")
|
353
|
-
|
354
|
-
# Call the callback if set
|
355
|
-
if @on_challenge
|
356
|
-
signature, extra = @on_challenge.call(message.authmethod, message.extra)
|
357
|
-
else
|
358
|
-
signature = nil
|
359
|
-
extra = nil
|
360
|
-
end
|
361
|
-
|
362
|
-
signature ||= ''
|
363
|
-
extra ||= {}
|
364
|
-
|
365
|
-
authenticate = Message::Authenticate.new(signature, extra)
|
366
|
-
self._send_message(authenticate)
|
367
|
-
|
368
|
-
elsif message.is_a? Message::Abort
|
369
|
-
# Log leaving the session
|
370
|
-
logger.info("#{self.class.name} left session '#{message.reason}'")
|
371
|
-
|
372
|
-
# Call the callback if it is set
|
373
|
-
@on_leave.call(message.reason, message.details) unless @on_leave.nil?
|
374
|
-
end
|
375
|
-
|
376
|
-
# Wamp Session is open
|
377
|
-
else
|
378
|
-
|
379
|
-
# If goodbye, close the session
|
380
|
-
if message.is_a? Message::Goodbye
|
381
|
-
|
382
|
-
# If we didn't send the goodbye, respond
|
383
|
-
unless self._goodbye_sent
|
384
|
-
goodbye = Message::Goodbye.new({}, 'wamp.error.goodbye_and_out')
|
385
|
-
self._send_message(goodbye)
|
386
|
-
end
|
387
|
-
|
388
|
-
# Close out session
|
389
|
-
self.id = nil
|
390
|
-
self.realm = nil
|
391
|
-
self._goodbye_sent = false
|
392
|
-
@on_leave.call(message.reason, message.details) unless @on_leave.nil?
|
393
|
-
|
394
|
-
else
|
395
|
-
|
396
|
-
# Else this is a normal message. Lookup the handler and call it
|
397
|
-
type = message.is_a?(Message::Error) ? message.request_type : message.class.type
|
398
|
-
handler = HANDLER_LOOKUP[type]
|
399
|
-
|
400
|
-
if handler != nil
|
401
|
-
handler.call(self, message)
|
402
|
-
else
|
403
|
-
logger.error("#{self.class.name} unknown message type '#{type}'")
|
404
|
-
end
|
405
|
-
end
|
406
|
-
end
|
407
|
-
|
408
|
-
end
|
409
|
-
|
410
|
-
#region Subscribe Logic
|
411
|
-
|
412
140
|
# Subscribes to a topic
|
141
|
+
#
|
413
142
|
# @param topic [String] The topic to subscribe to
|
414
143
|
# @param handler [lambda] The handler(args, kwargs, details) when an event is received
|
415
144
|
# @param options [Hash] The options for the subscription
|
416
145
|
# @param callback [block] The callback(subscription, error) called to signal if the subscription was a success or not
|
417
146
|
def subscribe(topic, handler, options={}, &callback)
|
418
|
-
|
419
|
-
raise RuntimeError, "Session must be open to call 'subscribe'"
|
420
|
-
end
|
147
|
+
check_open
|
421
148
|
|
149
|
+
# Check params
|
422
150
|
self.class.check_uri('topic', topic)
|
423
151
|
self.class.check_dict('options', options)
|
424
152
|
self.class.check_nil('handler', handler, false)
|
425
153
|
|
426
|
-
#
|
427
|
-
request
|
428
|
-
self._requests[:subscribe][request] = {t: topic, h: handler, o: options, c: callback}
|
429
|
-
|
430
|
-
# Send the message
|
431
|
-
subscribe = Message::Subscribe.new(request, options, topic)
|
432
|
-
self._send_message(subscribe)
|
154
|
+
# Make the request
|
155
|
+
make_request(:subscribe, :request, topic, handler, options, &callback)
|
433
156
|
end
|
434
157
|
|
435
|
-
# Processes the response to a subscribe request
|
436
|
-
# @param msg [Message::Subscribed] The response from the subscribe
|
437
|
-
def _process_SUBSCRIBED(msg)
|
438
|
-
|
439
|
-
# Remove the pending subscription, add it to the registered ones, and inform the caller
|
440
|
-
s = self._requests[:subscribe].delete(msg.subscribe_request)
|
441
|
-
if s
|
442
|
-
|
443
|
-
details = {}
|
444
|
-
details[:topic] = s[:t] unless details[:topic]
|
445
|
-
details[:type] = 'subscribe'
|
446
|
-
details[:session] = self
|
447
|
-
|
448
|
-
n_s = Subscription.new(s[:t], s[:h], s[:o], self, msg.subscription)
|
449
|
-
self._subscriptions[msg.subscription] = n_s
|
450
|
-
c = s[:c]
|
451
|
-
c.call(n_s, nil, details) if c
|
452
|
-
end
|
453
|
-
|
454
|
-
end
|
455
|
-
|
456
|
-
# Processes an error from a request
|
457
|
-
# @param msg [Message::Error] The response from the subscribe
|
458
|
-
def _process_SUBSCRIBE_error(msg)
|
459
|
-
|
460
|
-
# Remove the pending subscription and inform the caller of the failure
|
461
|
-
s = self._requests[:subscribe].delete(msg.request_request)
|
462
|
-
if s
|
463
|
-
|
464
|
-
details = msg.details || {}
|
465
|
-
details[:topic] = s[:t] unless details[:topic]
|
466
|
-
details[:type] = 'subscribe'
|
467
|
-
details[:session] = self
|
468
|
-
|
469
|
-
c = s[:c]
|
470
|
-
c.call(nil, self._error_to_hash(msg), details) if c
|
471
|
-
end
|
472
|
-
|
473
|
-
end
|
474
|
-
|
475
|
-
# Processes and event from the broker
|
476
|
-
# @param msg [Message::Event] An event that was published
|
477
|
-
def _process_EVENT(msg)
|
478
|
-
|
479
|
-
args = msg.publish_arguments || []
|
480
|
-
kwargs = msg.publish_argumentskw || {}
|
481
|
-
|
482
|
-
s = self._subscriptions[msg.subscribed_subscription]
|
483
|
-
if s
|
484
|
-
details = msg.details || {}
|
485
|
-
details[:publication] = msg.published_publication
|
486
|
-
details[:session] = self
|
487
|
-
|
488
|
-
h = s.handler
|
489
|
-
h.call(args, kwargs, details) if h
|
490
|
-
end
|
491
|
-
|
492
|
-
end
|
493
|
-
|
494
|
-
#endregion
|
495
|
-
|
496
|
-
#region Unsubscribe Logic
|
497
|
-
|
498
158
|
# Unsubscribes from a subscription
|
159
|
+
#
|
499
160
|
# @param subscription [Subscription] The subscription object from when the subscription was created
|
500
161
|
# @param callback [block] The callback(subscription, error, details) called to signal if the subscription was a success or not
|
501
162
|
def unsubscribe(subscription, &callback)
|
502
|
-
|
503
|
-
raise RuntimeError, "Session must be open to call 'unsubscribe'"
|
504
|
-
end
|
163
|
+
check_open
|
505
164
|
|
165
|
+
# Check params
|
506
166
|
self.class.check_nil('subscription', subscription, false)
|
507
167
|
|
508
|
-
#
|
509
|
-
request
|
510
|
-
self._requests[:unsubscribe][request] = { s: subscription, c: callback }
|
511
|
-
|
512
|
-
# Send the message
|
513
|
-
unsubscribe = Message::Unsubscribe.new(request, subscription.id)
|
514
|
-
self._send_message(unsubscribe)
|
515
|
-
end
|
516
|
-
|
517
|
-
# Processes the response to a unsubscribe request
|
518
|
-
# @param msg [Message::Unsubscribed] The response from the unsubscribe
|
519
|
-
def _process_UNSUBSCRIBED(msg)
|
520
|
-
|
521
|
-
# Remove the pending unsubscription, add it to the registered ones, and inform the caller
|
522
|
-
s = self._requests[:unsubscribe].delete(msg.unsubscribe_request)
|
523
|
-
if s
|
524
|
-
n_s = s[:s]
|
525
|
-
self._subscriptions.delete(n_s.id)
|
526
|
-
|
527
|
-
details = {}
|
528
|
-
details[:topic] = s[:s].topic
|
529
|
-
details[:type] = 'unsubscribe'
|
530
|
-
details[:session] = self
|
531
|
-
|
532
|
-
c = s[:c]
|
533
|
-
c.call(n_s, nil, details) if c
|
534
|
-
end
|
535
|
-
|
168
|
+
# Make the request
|
169
|
+
make_request(:unsubscribe, :request, subscription, &callback)
|
536
170
|
end
|
537
171
|
|
538
|
-
|
539
|
-
# Processes an error from a request
|
540
|
-
# @param msg [Message::Error] The response from the subscribe
|
541
|
-
def _process_UNSUBSCRIBE_error(msg)
|
542
|
-
|
543
|
-
# Remove the pending subscription and inform the caller of the failure
|
544
|
-
s = self._requests[:unsubscribe].delete(msg.request_request)
|
545
|
-
if s
|
546
|
-
|
547
|
-
details = msg.details || {}
|
548
|
-
details[:topic] = s[:s].topic unless details[:topic]
|
549
|
-
details[:type] = 'unsubscribe'
|
550
|
-
details[:session] = self
|
551
|
-
|
552
|
-
c = s[:c]
|
553
|
-
c.call(nil, self._error_to_hash(msg), details) if c
|
554
|
-
end
|
555
|
-
|
556
|
-
end
|
557
|
-
|
558
|
-
#endregion
|
559
|
-
|
560
|
-
#region Publish Logic
|
561
|
-
|
562
172
|
# Publishes and event to a topic
|
173
|
+
#
|
563
174
|
# @param topic [String] The topic to publish the event to
|
564
175
|
# @param args [Array] The arguments
|
565
176
|
# @param kwargs [Hash] The keyword arguments
|
566
177
|
# @param options [Hash] The options for the publish
|
567
178
|
# @param callback [block] The callback(publish, error, details) called to signal if the publish was a success or not
|
568
179
|
def publish(topic, args=nil, kwargs=nil, options={}, &callback)
|
569
|
-
|
570
|
-
raise RuntimeError, "Session must be open to call 'publish'"
|
571
|
-
end
|
180
|
+
check_open
|
572
181
|
|
182
|
+
# Check params
|
573
183
|
self.class.check_uri('topic', topic)
|
574
184
|
self.class.check_dict('options', options)
|
575
185
|
self.class.check_list('args', args, true)
|
576
186
|
self.class.check_dict('kwargs', kwargs, true)
|
577
187
|
|
578
|
-
#
|
579
|
-
request
|
580
|
-
self._requests[:publish][request] = {t: topic, a: args, k: kwargs, o: options, c: callback} if options[:acknowledge]
|
581
|
-
|
582
|
-
# Send the message
|
583
|
-
publish = Message::Publish.new(request, options, topic, args, kwargs)
|
584
|
-
self._send_message(publish)
|
585
|
-
end
|
586
|
-
|
587
|
-
# Processes the response to a publish request
|
588
|
-
# @param msg [Message::Published] The response from the subscribe
|
589
|
-
def _process_PUBLISHED(msg)
|
590
|
-
|
591
|
-
# Remove the pending publish and alert the callback
|
592
|
-
p = self._requests[:publish].delete(msg.publish_request)
|
593
|
-
if p
|
594
|
-
|
595
|
-
details = {}
|
596
|
-
details[:topic] = p[:t]
|
597
|
-
details[:type] = 'publish'
|
598
|
-
details[:publication] = msg.publication
|
599
|
-
details[:session] = self
|
600
|
-
|
601
|
-
c = p[:c]
|
602
|
-
c.call(p, nil, details) if c
|
603
|
-
end
|
604
|
-
|
188
|
+
# Make the request
|
189
|
+
make_request(:publish, :request, topic, args, kwargs, options, &callback)
|
605
190
|
end
|
606
191
|
|
607
|
-
# Processes an error from a publish request
|
608
|
-
# @param msg [Message::Error] The response from the subscribe
|
609
|
-
def _process_PUBLISH_error(msg)
|
610
|
-
|
611
|
-
# Remove the pending publish and inform the caller of the failure
|
612
|
-
s = self._requests[:publish].delete(msg.request_request)
|
613
|
-
if s
|
614
|
-
|
615
|
-
details = msg.details || {}
|
616
|
-
details[:topic] = s[:t] unless details[:topic]
|
617
|
-
details[:type] = 'publish'
|
618
|
-
details[:session] = self
|
619
|
-
|
620
|
-
c = s[:c]
|
621
|
-
c.call(nil, self._error_to_hash(msg), details) if c
|
622
|
-
end
|
623
|
-
|
624
|
-
end
|
625
|
-
|
626
|
-
#endregion
|
627
|
-
|
628
|
-
#region Register Logic
|
629
|
-
|
630
192
|
# Register to a procedure
|
193
|
+
#
|
631
194
|
# @param procedure [String] The procedure to register for
|
632
195
|
# @param handler [lambda] The handler(args, kwargs, details) when an invocation is received
|
633
196
|
# @param options [Hash, nil] The options for the registration
|
634
197
|
# @param interrupt [lambda] The handler(request, mode) when an interrupt is received
|
635
198
|
# @param callback [block] The callback(registration, error, details) called to signal if the registration was a success or not
|
636
199
|
def register(procedure, handler, options=nil, interrupt=nil, &callback)
|
637
|
-
|
638
|
-
raise RuntimeError, "Session must be open to call 'register'"
|
639
|
-
end
|
200
|
+
check_open
|
640
201
|
|
641
202
|
options ||= {}
|
642
203
|
|
204
|
+
# Check params
|
643
205
|
self.class.check_uri('procedure', procedure)
|
644
206
|
self.class.check_nil('handler', handler, false)
|
645
207
|
|
646
|
-
#
|
647
|
-
request
|
648
|
-
self._requests[:register][request] = {p: procedure, h: handler, i: interrupt, o: options, c: callback}
|
649
|
-
|
650
|
-
# Send the message
|
651
|
-
register = Message::Register.new(request, options, procedure)
|
652
|
-
self._send_message(register)
|
653
|
-
end
|
654
|
-
|
655
|
-
# Processes the response to a register request
|
656
|
-
# @param msg [Message::Registered] The response from the subscribe
|
657
|
-
def _process_REGISTERED(msg)
|
658
|
-
|
659
|
-
# Remove the pending subscription, add it to the registered ones, and inform the caller
|
660
|
-
r = self._requests[:register].delete(msg.register_request)
|
661
|
-
if r
|
662
|
-
n_r = Registration.new(r[:p], r[:h], r[:o], r[:i], self, msg.registration)
|
663
|
-
self._registrations[msg.registration] = n_r
|
664
|
-
|
665
|
-
details = {}
|
666
|
-
details[:procedure] = r[:p]
|
667
|
-
details[:type] = 'register'
|
668
|
-
details[:session] = self
|
669
|
-
|
670
|
-
c = r[:c]
|
671
|
-
c.call(n_r, nil, details) if c
|
672
|
-
end
|
673
|
-
|
674
|
-
end
|
675
|
-
|
676
|
-
# Processes an error from a request
|
677
|
-
# @param msg [Message::Error] The response from the register
|
678
|
-
def _process_REGISTER_error(msg)
|
679
|
-
|
680
|
-
# Remove the pending registration and inform the caller of the failure
|
681
|
-
r = self._requests[:register].delete(msg.request_request)
|
682
|
-
if r
|
683
|
-
|
684
|
-
details = msg.details || {}
|
685
|
-
details[:procedure] = r[:p] unless details[:procedure]
|
686
|
-
details[:type] = 'register'
|
687
|
-
details[:session] = self
|
688
|
-
|
689
|
-
c = r[:c]
|
690
|
-
c.call(nil, self._error_to_hash(msg), details) if c
|
691
|
-
end
|
692
|
-
|
693
|
-
end
|
694
|
-
|
695
|
-
# Sends an error back to the caller
|
696
|
-
# @param request[Integer] - The request ID
|
697
|
-
# @param error
|
698
|
-
def _send_INVOCATION_error(request, error, check_defer=false)
|
699
|
-
# Prevent responses for defers that have already completed or had an error
|
700
|
-
if check_defer and not self._defers[request]
|
701
|
-
return
|
702
|
-
end
|
703
|
-
|
704
|
-
if error.nil?
|
705
|
-
error = CallError.new('wamp.error.runtime')
|
706
|
-
elsif not error.is_a?(CallError)
|
707
|
-
backtrace = error.is_a?(Exception) ? error.backtrace : nil
|
708
|
-
error = CallError.new('wamp.error.runtime', [error.to_s], { backtrace: backtrace })
|
709
|
-
end
|
710
|
-
|
711
|
-
error_msg = Message::Error.new(Message::Types::INVOCATION, request, {}, error.error, error.args, error.kwargs)
|
712
|
-
self._send_message(error_msg)
|
208
|
+
# Make the request
|
209
|
+
make_request(:register, :request, procedure, handler, options, interrupt, &callback)
|
713
210
|
end
|
714
211
|
|
715
212
|
# Sends a result for the invocation
|
213
|
+
#
|
716
214
|
# @param request [Integer] - The id of the request
|
717
215
|
# @param result [CallError, CallResult, anything] - If it is a CallError, the error will be returned
|
718
216
|
# @param options [Hash] - The options to be sent with the yield
|
719
217
|
def yield(request, result, options={}, check_defer=false)
|
720
|
-
|
721
|
-
if check_defer and not self._defers[request]
|
722
|
-
return
|
723
|
-
end
|
724
|
-
|
725
|
-
# Wrap the result accordingly
|
726
|
-
if result.nil?
|
727
|
-
result = CallResult.new
|
728
|
-
elsif result.is_a?(CallError)
|
729
|
-
# Do nothing
|
730
|
-
elsif not result.is_a?(CallResult)
|
731
|
-
result = CallResult.new([result])
|
732
|
-
end
|
733
|
-
|
734
|
-
# Send either the error or the response
|
735
|
-
if result.is_a?(CallError)
|
736
|
-
self._send_INVOCATION_error(request, result)
|
737
|
-
else
|
738
|
-
yield_msg = Message::Yield.new(request, options, result.args, result.kwargs)
|
739
|
-
self._send_message(yield_msg)
|
740
|
-
end
|
218
|
+
check_open
|
741
219
|
|
742
|
-
#
|
743
|
-
|
744
|
-
self._defers.delete(request)
|
745
|
-
end
|
220
|
+
# Call the registration yield method
|
221
|
+
self.registration.yield(request, result, options, check_defer)
|
746
222
|
end
|
747
223
|
|
748
|
-
|
749
|
-
# Processes and event from the broker
|
750
|
-
# @param msg [Message::Invocation] An procedure that was called
|
751
|
-
def _process_INVOCATION(msg)
|
752
|
-
|
753
|
-
request = msg.request
|
754
|
-
args = msg.call_arguments || []
|
755
|
-
kwargs = msg.call_argumentskw || {}
|
756
|
-
|
757
|
-
details = msg.details || {}
|
758
|
-
details[:request] = request
|
759
|
-
details[:session] = self
|
760
|
-
|
761
|
-
r = self._registrations[msg.registered_registration]
|
762
|
-
if r
|
763
|
-
h = r.handler
|
764
|
-
if h
|
765
|
-
begin
|
766
|
-
value = h.call(args, kwargs, details)
|
767
|
-
|
768
|
-
# If a defer was returned, handle accordingly
|
769
|
-
if value.is_a? Defer::CallDefer
|
770
|
-
value.request = request
|
771
|
-
value.registration = msg.registered_registration
|
772
|
-
|
773
|
-
# Store the defer
|
774
|
-
self._defers[request] = value
|
775
|
-
|
776
|
-
# On complete, send the result
|
777
|
-
value.on_complete do |defer, result|
|
778
|
-
self.yield(defer.request, result, {}, true)
|
779
|
-
end
|
780
|
-
|
781
|
-
# On error, send the error
|
782
|
-
value.on_error do |defer, error|
|
783
|
-
error = CallError.new("wamp.error.runtime", [error]) if error.is_a?(String)
|
784
|
-
self.yield(defer.request, error, {}, true)
|
785
|
-
end
|
786
|
-
|
787
|
-
# For progressive, return the progress
|
788
|
-
if value.is_a? Defer::ProgressiveCallDefer
|
789
|
-
value.on_progress do |defer, result|
|
790
|
-
self.yield(defer.request, result, {progress: true}, true)
|
791
|
-
end
|
792
|
-
end
|
793
|
-
|
794
|
-
# Else it was a normal response
|
795
|
-
else
|
796
|
-
self.yield(request, value)
|
797
|
-
end
|
798
|
-
|
799
|
-
rescue Exception => error
|
800
|
-
self._send_INVOCATION_error(request, error)
|
801
|
-
end
|
802
|
-
|
803
|
-
end
|
804
|
-
end
|
805
|
-
end
|
806
|
-
|
807
|
-
# Processes the interrupt
|
808
|
-
# @param msg [Message::Interrupt] An interrupt to a procedure
|
809
|
-
def _process_INTERRUPT(msg)
|
810
|
-
|
811
|
-
request = msg.invocation_request
|
812
|
-
mode = msg.options[:mode]
|
813
|
-
|
814
|
-
defer = self._defers[request]
|
815
|
-
if defer
|
816
|
-
r = self._registrations[defer.registration]
|
817
|
-
if r
|
818
|
-
# If it exists, call the interrupt handler to inform it of the interrupt
|
819
|
-
i = r.i_handler
|
820
|
-
error = nil
|
821
|
-
if i
|
822
|
-
begin
|
823
|
-
error = i.call(request, mode)
|
824
|
-
rescue Exception => e
|
825
|
-
error = e
|
826
|
-
end
|
827
|
-
end
|
828
|
-
|
829
|
-
error ||= 'interrupt'
|
830
|
-
|
831
|
-
# Send the error back to the client
|
832
|
-
self._send_INVOCATION_error(request, error, true)
|
833
|
-
end
|
834
|
-
|
835
|
-
# Delete the defer
|
836
|
-
self._defers.delete(request)
|
837
|
-
end
|
838
|
-
|
839
|
-
end
|
840
|
-
|
841
|
-
#endregion
|
842
|
-
|
843
|
-
#region Unregister Logic
|
844
|
-
|
845
224
|
# Unregisters from a procedure
|
225
|
+
#
|
846
226
|
# @param registration [Registration] The registration object from when the registration was created
|
847
227
|
# @param callback [block] The callback(registration, error, details) called to signal if the unregistration was a success or not
|
848
228
|
def unregister(registration, &callback)
|
849
|
-
|
850
|
-
raise RuntimeError, "Session must be open to call 'unregister'"
|
851
|
-
end
|
229
|
+
check_open
|
852
230
|
|
231
|
+
# Check params
|
853
232
|
self.class.check_nil('registration', registration, false)
|
854
233
|
|
855
|
-
#
|
856
|
-
request
|
857
|
-
self._requests[:unregister][request] = { r: registration, c: callback }
|
858
|
-
|
859
|
-
# Send the message
|
860
|
-
unregister = Message::Unregister.new(request, registration.id)
|
861
|
-
self._send_message(unregister)
|
234
|
+
# Make the request
|
235
|
+
make_request(:unregister, :request, registration, &callback)
|
862
236
|
end
|
863
237
|
|
864
|
-
# Processes the response to a unregister request
|
865
|
-
# @param msg [Message::Unregistered] The response from the unsubscribe
|
866
|
-
def _process_UNREGISTERED(msg)
|
867
|
-
|
868
|
-
# Remove the pending unregistration, add it to the registered ones, and inform the caller
|
869
|
-
r = self._requests[:unregister].delete(msg.unregister_request)
|
870
|
-
if r
|
871
|
-
r_s = r[:r]
|
872
|
-
self._registrations.delete(r_s.id)
|
873
|
-
|
874
|
-
details = {}
|
875
|
-
details[:procedure] = r_s.procedure
|
876
|
-
details[:type] = 'unregister'
|
877
|
-
details[:session] = self
|
878
|
-
|
879
|
-
c = r[:c]
|
880
|
-
c.call(r_s, nil, details) if c
|
881
|
-
end
|
882
|
-
|
883
|
-
end
|
884
|
-
|
885
|
-
# Processes an error from a request
|
886
|
-
# @param msg [Message::Error] The response from the subscribe
|
887
|
-
def _process_UNREGISTER_error(msg)
|
888
|
-
|
889
|
-
# Remove the pending subscription and inform the caller of the failure
|
890
|
-
r = self._requests[:unregister].delete(msg.request_request)
|
891
|
-
if r
|
892
|
-
|
893
|
-
details = msg.details || {}
|
894
|
-
details[:procedure] = r[:r].procedure unless details[:procedure]
|
895
|
-
details[:type] = 'unregister'
|
896
|
-
details[:session] = self
|
897
|
-
|
898
|
-
c = r[:c]
|
899
|
-
c.call(nil, self._error_to_hash(msg), details) if c
|
900
|
-
end
|
901
|
-
|
902
|
-
end
|
903
|
-
|
904
|
-
#endregion
|
905
|
-
|
906
|
-
#region Call Logic
|
907
|
-
|
908
238
|
# Publishes and event to a topic
|
239
|
+
#
|
909
240
|
# @param procedure [String] The procedure to invoke
|
910
241
|
# @param args [Array] The arguments
|
911
242
|
# @param kwargs [Hash] The keyword arguments
|
@@ -913,106 +244,108 @@ module Wamp
|
|
913
244
|
# @param callback [block] The callback(result, error, details) called to signal if the call was a success or not
|
914
245
|
# @return [Call] An object representing the call
|
915
246
|
def call(procedure, args=nil, kwargs=nil, options={}, &callback)
|
916
|
-
|
917
|
-
raise RuntimeError, "Session must be open to call 'call'"
|
918
|
-
end
|
247
|
+
check_open
|
919
248
|
|
249
|
+
# Check params
|
920
250
|
self.class.check_uri('procedure', procedure)
|
921
251
|
self.class.check_dict('options', options)
|
922
252
|
self.class.check_list('args', args, true)
|
923
253
|
self.class.check_dict('kwargs', kwargs, true)
|
924
254
|
|
925
|
-
#
|
926
|
-
|
927
|
-
self._requests[:call][request] = {p: procedure, a: args, k: kwargs, o: options, c: callback}
|
928
|
-
|
929
|
-
# Send the message
|
930
|
-
msg = Message::Call.new(request, options, procedure, args, kwargs)
|
931
|
-
self._send_message(msg)
|
255
|
+
# Make the request
|
256
|
+
request_id = make_request(:call, :request, procedure, args, kwargs, options, &callback)
|
932
257
|
|
933
|
-
|
258
|
+
# Create the call object
|
259
|
+
call = Request::CallObject.new(self, request_id)
|
934
260
|
|
935
261
|
# Timeout Logic
|
936
262
|
if options[:timeout] and options[:timeout] > 0
|
263
|
+
# Once the timer expires, if the call hasn't completed, cancel it
|
937
264
|
self.transport.add_timer(options[:timeout]) do
|
938
|
-
|
939
|
-
if self._requests[:call][call.id]
|
940
|
-
call.cancel
|
941
|
-
end
|
265
|
+
call.cancel
|
942
266
|
end
|
943
267
|
end
|
944
268
|
|
945
269
|
call
|
946
270
|
end
|
947
271
|
|
948
|
-
#
|
949
|
-
#
|
950
|
-
|
951
|
-
|
952
|
-
|
272
|
+
# Cancels a call
|
273
|
+
#
|
274
|
+
# @param call [Call] - The call object
|
275
|
+
# @param mode [String] - The mode of the skip. Options are 'skip', 'kill', 'killnowait'
|
276
|
+
def cancel(call, mode='skip')
|
277
|
+
check_open
|
953
278
|
|
954
|
-
|
279
|
+
# Check params
|
280
|
+
self.class.check_nil('call', call, false)
|
955
281
|
|
956
|
-
#
|
957
|
-
|
282
|
+
# Cancel the request
|
283
|
+
make_request(:call, :cancel, call.id, mode)
|
284
|
+
end
|
958
285
|
|
959
|
-
|
960
|
-
details[:procedure] = call[:p] unless details[:procedure]
|
961
|
-
details[:type] = 'call'
|
962
|
-
details[:session] = self
|
286
|
+
private
|
963
287
|
|
964
|
-
|
965
|
-
|
288
|
+
def check_closed
|
289
|
+
if is_open?
|
290
|
+
raise RuntimeError, "session must be closed to call this method"
|
966
291
|
end
|
292
|
+
end
|
967
293
|
|
294
|
+
def check_open
|
295
|
+
unless is_open?
|
296
|
+
raise RuntimeError, "session must be open to call this method"
|
297
|
+
end
|
968
298
|
end
|
969
299
|
|
970
|
-
|
971
|
-
|
972
|
-
|
300
|
+
def make_request(name, method, *args, &callback)
|
301
|
+
self.request[name].send(method, *args, &callback)
|
302
|
+
end
|
973
303
|
|
974
|
-
|
975
|
-
|
976
|
-
|
304
|
+
def logger
|
305
|
+
Wamp::Client.logger
|
306
|
+
end
|
977
307
|
|
978
|
-
|
979
|
-
details[:procedure] = call[:p] unless details[:procedure]
|
980
|
-
details[:type] = 'call'
|
981
|
-
details[:session] = self
|
308
|
+
def send_message(msg)
|
982
309
|
|
983
|
-
|
984
|
-
|
985
|
-
end
|
310
|
+
# Log the message
|
311
|
+
logger.debug("#{self.class.name} TX: #{msg.to_s}")
|
986
312
|
|
313
|
+
# Send it to the transport
|
314
|
+
self.transport.send_message(msg.payload)
|
987
315
|
end
|
988
316
|
|
989
|
-
|
317
|
+
def receive_message(msg)
|
990
318
|
|
991
|
-
|
319
|
+
# Print the raw message
|
320
|
+
logger.debug("#{self.class.name} RX(raw): #{msg.to_s}")
|
992
321
|
|
993
|
-
|
994
|
-
|
995
|
-
# @param mode [String] - The mode of the skip. Options are 'skip', 'kill', 'killnowait'
|
996
|
-
def cancel(call, mode='skip')
|
997
|
-
unless is_open?
|
998
|
-
raise RuntimeError, "Session must be open to call 'cancel'"
|
999
|
-
end
|
322
|
+
# Parse the WAMP message
|
323
|
+
message = Message.parse(msg)
|
1000
324
|
|
1001
|
-
|
325
|
+
# Print the parsed WAMP message
|
326
|
+
logger.debug("#{self.class.name} RX: #{message.to_s}")
|
1002
327
|
|
1003
|
-
#
|
1004
|
-
|
1005
|
-
self._send_message(cancel)
|
1006
|
-
end
|
328
|
+
# Get the lookup based on the state of the session
|
329
|
+
lookup = self.is_open? ? OPEN_SESSION_METHOD_LOOKUP : CLOSED_SESSION_METHOD_LOOKUP
|
1007
330
|
|
1008
|
-
|
331
|
+
# Get the type of message
|
332
|
+
type = message.is_a?(Message::Error) ? message.request_type : message.class.type
|
1009
333
|
|
1010
|
-
|
334
|
+
# Get the handler
|
335
|
+
handler = lookup[type]
|
1011
336
|
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
337
|
+
# Execute the handler
|
338
|
+
if handler != nil
|
339
|
+
# Catch any standard exception and log it
|
340
|
+
begin
|
341
|
+
handler.call(self, message)
|
342
|
+
rescue StandardError => e
|
343
|
+
logger.error("#{self.class.name} - #{e.message}")
|
344
|
+
e.backtrace.each { |line| logger.error(" #{line}") }
|
345
|
+
end
|
346
|
+
else
|
347
|
+
logger.error("#{self.class.name} unknown message type '#{type}'")
|
348
|
+
end
|
1016
349
|
end
|
1017
350
|
|
1018
351
|
end
|