ducts-client 0.1.2 → 0.4.4
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/lib/ducts/client.rb +126 -67
- data/lib/ducts/client/version.rb +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e4ed02a6ed450d3495ea4d27af20b735e50959f1d95042dccf7afcca9331e079
|
|
4
|
+
data.tar.gz: f8a5f500b92af0ff4a6f3fca4f4590b480534976c412c969944919ecb7d5c261
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e7621536c5e0dafabfa1d6f47eb0d69a6f96188251e2c83ddc33aeb1d58abc8a32d5ff1b88d7c39dad1c0040d063f428457e2fde85aca1be8c3d4af541ed06e9
|
|
7
|
+
data.tar.gz: 611bd6b7d8bf79eef1abff322f98723e9239a5f63a6f94443baf0a104263eb937d626d06ddaf8cda5884144deb72f4c50c005ff439ce0ce3bd69c64441c919fd
|
data/lib/ducts/client.rb
CHANGED
|
@@ -56,6 +56,8 @@ module Ducts
|
|
|
56
56
|
end
|
|
57
57
|
end
|
|
58
58
|
|
|
59
|
+
DuctEventHandlerReturnValue = Struct.new(:value)
|
|
60
|
+
|
|
59
61
|
class ConnectionEventListener < DuctEventListener
|
|
60
62
|
attr_writer :onopen, :onclose, :onerror, :onmessage
|
|
61
63
|
def onopen(event)
|
|
@@ -118,7 +120,9 @@ module Ducts
|
|
|
118
120
|
|
|
119
121
|
@_last_rid = nil
|
|
120
122
|
@_ws = nil
|
|
121
|
-
@
|
|
123
|
+
@_waiting_message_completion = Hash.new
|
|
124
|
+
@_waiting_closed_completion = Array.new
|
|
125
|
+
@_loop_queues = Hash.new
|
|
122
126
|
end
|
|
123
127
|
|
|
124
128
|
def next_rid
|
|
@@ -130,29 +134,13 @@ module Ducts
|
|
|
130
134
|
next_id
|
|
131
135
|
end
|
|
132
136
|
|
|
133
|
-
def open(wsd_url, uuid = nil, **params)
|
|
134
|
-
_open(wsd_url, uuid, **params)
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
def reconnect
|
|
138
|
-
_reconnect
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
def send(rid, eid, data)
|
|
142
|
-
_send(rid, eid, data)
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
def call(eid, data)
|
|
146
|
-
_call(eid, data)
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
def close
|
|
150
|
-
_close
|
|
151
|
-
end
|
|
152
|
-
|
|
153
137
|
def set_event_handler(event_id, &handler)
|
|
154
138
|
@_event_handler ||= {}
|
|
155
|
-
|
|
139
|
+
if handler
|
|
140
|
+
@_event_handler.store(event_id, handler)
|
|
141
|
+
else
|
|
142
|
+
@_event_handler.delete(event_id)
|
|
143
|
+
end
|
|
156
144
|
end
|
|
157
145
|
|
|
158
146
|
def state
|
|
@@ -163,16 +151,16 @@ module Ducts
|
|
|
163
151
|
end
|
|
164
152
|
end
|
|
165
153
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
if
|
|
169
|
-
|
|
170
|
-
|
|
154
|
+
def reconnect
|
|
155
|
+
completion = EM::Completion.new
|
|
156
|
+
if @_ws
|
|
157
|
+
completion.succeed(self)
|
|
158
|
+
return completion;
|
|
171
159
|
end
|
|
172
|
-
return if @_ws
|
|
173
160
|
Faye::WebSocket::Client.new(@WSD['websocket_url_reconnect']).tap do |ws|
|
|
174
161
|
ws.on(:open) do |event|
|
|
175
162
|
@_ws = ws
|
|
163
|
+
completion.succeed(self)
|
|
176
164
|
connection_event = DuctConnectionEvent.new('onopen', event)
|
|
177
165
|
_onreconnect(connection_event)
|
|
178
166
|
@connection_listener.onopen(connection_event)
|
|
@@ -192,10 +180,15 @@ module Ducts
|
|
|
192
180
|
@connection_listener.onerror(connection_event)
|
|
193
181
|
end
|
|
194
182
|
end
|
|
183
|
+
completion
|
|
195
184
|
end
|
|
196
185
|
|
|
197
|
-
def
|
|
198
|
-
|
|
186
|
+
def open(wsd_url, uuid = nil, **params)
|
|
187
|
+
completion = EM::Completion.new
|
|
188
|
+
if @_ws
|
|
189
|
+
completion.succeed(self)
|
|
190
|
+
return completion;
|
|
191
|
+
end
|
|
199
192
|
begin
|
|
200
193
|
query = '?uuid=' + (uuid || 'dummy') + params.map{ |k, v| "&#{k}=#{v}" }.join
|
|
201
194
|
uri = URI.parse(wsd_url + query)
|
|
@@ -210,6 +203,7 @@ module Ducts
|
|
|
210
203
|
Faye::WebSocket::Client.new(@WSD['websocket_url']).tap do |ws|
|
|
211
204
|
ws.on(:open) do |event|
|
|
212
205
|
@_ws = ws
|
|
206
|
+
completion.succeed(self)
|
|
213
207
|
connection_event = DuctConnectionEvent.new('onopen', event)
|
|
214
208
|
_onopen(connection_event)
|
|
215
209
|
@connection_listener.onopen(connection_event)
|
|
@@ -225,6 +219,19 @@ module Ducts
|
|
|
225
219
|
@connection_listener.onerror(connection_event)
|
|
226
220
|
end
|
|
227
221
|
ws.on(:close) do |event|
|
|
222
|
+
@_ws = nil
|
|
223
|
+
case event.code
|
|
224
|
+
when 1000
|
|
225
|
+
@_waiting_closed_completion.each do |waiting_closed_completion|
|
|
226
|
+
waiting_closed_completion.succeed(event)
|
|
227
|
+
end
|
|
228
|
+
else
|
|
229
|
+
p event.code
|
|
230
|
+
@_waiting_closed_completion.each do |waiting_closed_completion|
|
|
231
|
+
waiting_closed_completion.fail(event)
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
@_waiting_closed_completion.clear
|
|
228
235
|
connection_event = DuctConnectionEvent.new('onclose', event)
|
|
229
236
|
@connection_listener.onclose(connection_event)
|
|
230
237
|
end
|
|
@@ -232,67 +239,69 @@ module Ducts
|
|
|
232
239
|
rescue => error
|
|
233
240
|
@connection_listener.onerror(DuctConnectionEvent.new('onerror', error))
|
|
234
241
|
end
|
|
242
|
+
completion
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
def event_send(rid, eid, data)
|
|
246
|
+
msgpack = [ rid, eid, data ].to_msgpack
|
|
247
|
+
@_ws.send(msgpack.chars.map(&:ord))
|
|
248
|
+
rid
|
|
235
249
|
end
|
|
236
250
|
|
|
251
|
+
def event_call(eid, data)
|
|
252
|
+
rid = next_rid
|
|
253
|
+
event_send(rid, eid, data)
|
|
254
|
+
warn Message.construct(Message::Level::WARNING, 'request ID is duplicated.') if @_waiting_message_completion.keys.include? rid
|
|
255
|
+
EM::Completion.new.tap { |completion| @_waiting_message_completion[rid] = completion }
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
def close
|
|
259
|
+
completion = EM::Completion.new
|
|
260
|
+
if @_ws
|
|
261
|
+
@_ws.close
|
|
262
|
+
@_waiting_closed_completion.push(completion)
|
|
263
|
+
else
|
|
264
|
+
completion.succeed(nil)
|
|
265
|
+
end
|
|
266
|
+
completion
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
private
|
|
237
270
|
def _onopen(event)
|
|
238
271
|
@_send_timestamp = Time.now.to_f
|
|
239
272
|
@_time_offset = 0
|
|
240
273
|
@_time_latency = 0
|
|
241
274
|
@_time_count = 0
|
|
242
|
-
set_event_handler(@EVENT['ALIVE_MONITORING']
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
@_time_offset = (@_time_offset * @_time_count + new_offset) / (@_time_count + 1)
|
|
249
|
-
@_time_latency = (@_time_latency * @_time_count + new_latency) / (@_time_count + 1)
|
|
250
|
-
@_time_count += 1
|
|
251
|
-
end
|
|
275
|
+
set_event_handler(@EVENT['ALIVE_MONITORING'], &method(:_alive_monitoring_handler))
|
|
276
|
+
set_event_handler(@EVENT['LOOP_RESPONSE_START'], &method(:_loop_response_handler))
|
|
277
|
+
set_event_handler(@EVENT['LOOP_RESPONSE_NEXT'], &method(:_loop_response_handler))
|
|
278
|
+
set_event_handler(@EVENT['LOOP_RESPONSE_END'], &method(:_loop_response_end_handler))
|
|
279
|
+
set_event_handler(@EVENT['DIVIDED_RESPONSE_APPEND'], &method(:_divided_response_append_handler))
|
|
280
|
+
set_event_handler(@EVENT['DIVIDED_RESPONSE_END'], &method(:_divided_response_end_handler))
|
|
252
281
|
rid = next_rid
|
|
253
282
|
eid = @EVENT['ALIVE_MONITORING']
|
|
254
283
|
value = @_send_timestamp
|
|
255
|
-
|
|
284
|
+
event_send(rid, eid, value)
|
|
256
285
|
end
|
|
257
286
|
|
|
258
287
|
def _onreconnect(connection_event)
|
|
259
288
|
end
|
|
260
289
|
|
|
261
|
-
def _send(rid, eid, data)
|
|
262
|
-
msgpack = [ rid, eid, data ].to_msgpack
|
|
263
|
-
@_ws.send(msgpack.chars.map(&:ord))
|
|
264
|
-
rid
|
|
265
|
-
end
|
|
266
|
-
|
|
267
|
-
def _call(eid, data)
|
|
268
|
-
rid = next_rid
|
|
269
|
-
_send(rid, eid, data)
|
|
270
|
-
raise if @_waiting_completion.keys.include? rid
|
|
271
|
-
EM::Completion.new.tap { |completion| @_waiting_completion[rid] = completion }
|
|
272
|
-
end
|
|
273
|
-
|
|
274
|
-
def _close
|
|
275
|
-
begin
|
|
276
|
-
@_ws.close if @_ws
|
|
277
|
-
ensure
|
|
278
|
-
@_ws = nil
|
|
279
|
-
end
|
|
280
|
-
end
|
|
281
|
-
|
|
282
290
|
def _onmessage(connection_event)
|
|
283
291
|
begin
|
|
284
292
|
rid, eid, data = %i(rid eid data).map{ |name| connection_event.source.public_send(name) }
|
|
285
293
|
begin
|
|
286
294
|
@catchall_event_handler.call(rid, eid, data)
|
|
287
295
|
handle = @_event_handler[eid]
|
|
288
|
-
handle
|
|
289
|
-
handle.call(rid, eid, data)
|
|
290
|
-
|
|
296
|
+
handle ||= @uncaught_event_handler
|
|
297
|
+
ret = handle.call(rid, eid, data)
|
|
298
|
+
handled_data = (ret.instance_of? DuctEventHandlerReturnValue)? ret.value : data
|
|
299
|
+
completion = @_waiting_message_completion.delete(rid)
|
|
291
300
|
if completion
|
|
292
301
|
if eid > 0
|
|
293
|
-
completion.succeed(
|
|
302
|
+
completion.succeed(handled_data)
|
|
294
303
|
else
|
|
295
|
-
completion.fail(DuctError.
|
|
304
|
+
completion.fail(DuctError.exception(handled_data))
|
|
296
305
|
end
|
|
297
306
|
end
|
|
298
307
|
rescue => error
|
|
@@ -302,5 +311,55 @@ module Ducts
|
|
|
302
311
|
@event_error_handler.call(-1, -1, nil, error)
|
|
303
312
|
end
|
|
304
313
|
end
|
|
314
|
+
|
|
315
|
+
def _alive_monitoring_handler(rid, eid, data)
|
|
316
|
+
client_received = Time.now.to_f
|
|
317
|
+
server_sent, server_received = data
|
|
318
|
+
client_sent = @_send_timestamp
|
|
319
|
+
new_offset = ((server_received - client_sent) - (client_received - server_sent)) / 2
|
|
320
|
+
new_latency = ((client_received - client_sent) - (server_sent - server_received)) / 2
|
|
321
|
+
@_time_offset = (@_time_offset * @_time_count + new_offset) / (@_time_count + 1)
|
|
322
|
+
@_time_latency = (@_time_latency * @_time_count + new_latency) / (@_time_count + 1)
|
|
323
|
+
@_time_count += 1
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
def _loop_response_handler(rid, eid, data)
|
|
327
|
+
warn Message.construct(Message::Level::WARNING, 'loop response has error.') if eid.negative?
|
|
328
|
+
source_eid = data[1]
|
|
329
|
+
source_data = data[2]
|
|
330
|
+
@catchall_event_handler.call(rid, source_eid, source_data)
|
|
331
|
+
handle = @_event_handler[source_eid.abs]
|
|
332
|
+
handle ||= @uncaught_event_handler
|
|
333
|
+
ret = handle.call(rid, source_eid, source_data)
|
|
334
|
+
handled_source_data = (ret.instance_of? DuctEventHandlerReturnValue)? ret.value : source_data
|
|
335
|
+
@_loop_queues[rid] ||= EM::Queue.new
|
|
336
|
+
queue = @_loop_queues[rid]
|
|
337
|
+
queue.push(handled_source_data) if handled_source_data
|
|
338
|
+
DuctEventHandlerReturnValue.new(queue)
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
def _loop_response_end_handler(rid, eid, data)
|
|
342
|
+
warn Message.construct(Message::Level::WARNING, 'loop response end has error.') if eid.negative?
|
|
343
|
+
source_eid = data[1]
|
|
344
|
+
source_data = data[2]
|
|
345
|
+
warn Message.construct(Message::Level::WARNING, "loop response end has data: #{source_data}.") if source_data
|
|
346
|
+
@catchall_event_handler.call(rid, source_eid, source_data)
|
|
347
|
+
handle = @_event_handler[source_eid.abs]
|
|
348
|
+
handle ||= @uncaught_event_handler
|
|
349
|
+
handle.call(rid, source_eid, source_data)
|
|
350
|
+
queue = @_loop_queues.delete(rid)
|
|
351
|
+
queue.push(nil)
|
|
352
|
+
DuctEventHandlerReturnValue.new(source_eid)
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
def _divided_response_append_handler(rid, eid, data)
|
|
356
|
+
raise 'Not implemented.'
|
|
357
|
+
# TODO
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
def _divided_response_end_handler(rid, eid, data)
|
|
361
|
+
raise 'Not implemented.'
|
|
362
|
+
# TODO
|
|
363
|
+
end
|
|
305
364
|
end
|
|
306
365
|
end
|
data/lib/ducts/client/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ducts-client
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kenshiro Ueda
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2021-
|
|
11
|
+
date: 2021-06-11 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: faye-websocket
|