Skip to content

Commit e66d4e7

Browse files
committed
handling situations when web socket server or client are disconnected
1 parent 4c06b94 commit e66d4e7

File tree

2 files changed

+53
-18
lines changed

2 files changed

+53
-18
lines changed

bitdust/interface/routed_web_socket.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,10 +167,12 @@ def stop_client(url):
167167
except Empty:
168168
break
169169
_WebSocketQueue[url].put_nowait((None, None))
170-
if ws(url):
170+
_ws = ws(url)
171+
if _ws:
172+
_ws.close()
173+
else:
171174
if _Debug:
172175
lg.dbg(_DebugLevel, 'websocket %s already closed' % url)
173-
ws(url).close()
174176

175177

176178
def shutdown_clients():
@@ -423,6 +425,7 @@ def init(self):
423425
self.handshaked_routers = []
424426
self.server_code = None
425427
self.device_name = None
428+
self.client_connected = False
426429

427430
def state_changed(self, oldstate, newstate, event, *args, **kwargs):
428431
"""
@@ -442,6 +445,7 @@ def to_json(self, short=True):
442445
'connected_routers': self.handshaked_routers,
443446
'server_code': self.server_code,
444447
'device_name': self.device_name,
448+
'client_connected': self.client_connected,
445449
})
446450
return ret
447451

@@ -456,6 +460,7 @@ def on_incoming_message(self, url, json_data):
456460
cmd = json_data.get('cmd')
457461
if cmd == 'api':
458462
self.active_router_url = url
463+
self.client_connected = True
459464
self.event('api-message', url=url, json_data=json_data)
460465
return True
461466
if cmd == 'handshake-accepted':
@@ -485,11 +490,17 @@ def on_incoming_message(self, url, json_data):
485490
return False
486491
self.on_server_code_received(signature=signature, encrypted_server_code=encrypted_server_code)
487492
return True
493+
if cmd == 'client-disconnected':
494+
self.client_connected = False
495+
return True
488496
return False
489497

490498
def on_outgoing_message(self, json_data):
491499
if _Debug:
492-
lg.args(_DebugLevel, json_data)
500+
lg.args(_DebugLevel, client_connected=self.client_connected, d=json_data)
501+
if json_data.get('cmd') == 'push':
502+
if not self.client_connected:
503+
return False
493504
if self.state != 'READY':
494505
lg.warn('skip sending api message to client, %r state is %r' % (self, self.state))
495506
return False

bitdust/interface/web_socket_transmitter.py

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -345,10 +345,10 @@ def buildProtocol(self, addr):
345345
def do_process_incoming_message(transport, json_data, raw_data):
346346
global MAX_KNOWN_ROUTES
347347
route_id = transport.route_id
348-
direction = transport.direction
348+
transport_direction = transport.direction
349349
if _Debug:
350-
lg.args(_DebugLevel, route_id=route_id, direction=direction, json_data=json_data)
351-
if route_id is None and direction is None:
350+
lg.args(_DebugLevel, route_id=route_id, direction=transport_direction, json_data=json_data)
351+
if route_id is None and transport_direction is None:
352352
if json_data.get('cmd') == 'connect-request':
353353
if len(routes()) >= MAX_KNOWN_ROUTES:
354354
if _Debug:
@@ -368,18 +368,18 @@ def do_process_incoming_message(transport, json_data, raw_data):
368368
lg.exc()
369369
return False
370370
if _Debug:
371-
lg.out(_DebugLevel, ' wrote %d bytes to %s/%s at %r' % (len(response_raw_data), route_id, direction, transport))
371+
lg.out(_DebugLevel, ' wrote %d bytes to %s/%s at %r' % (len(response_raw_data), route_id, transport_direction, transport))
372372
return True
373373
return False
374374
if not route_id:
375375
lg.warn('unknown route ID: %r' % transport)
376376
return False
377-
if not direction:
377+
if not transport_direction:
378378
lg.warn('route direction was not identified: %r' % transport)
379379
return False
380380
cmd = json_data.get('cmd')
381381
if cmd == 'handshake':
382-
if json_data.get('internal') and direction == 'internal':
382+
if json_data.get('internal') and transport_direction == 'internal':
383383
route_info = routes(route_id)
384384
route_url = route_info['route_url'] if route_info else None
385385
if not route_url:
@@ -396,7 +396,7 @@ def do_process_incoming_message(transport, json_data, raw_data):
396396
lg.exc()
397397
return False
398398
if _Debug:
399-
lg.out(_DebugLevel, ' wrote %d bytes to %s/%s at %r' % (len(response_raw_data), route_id, direction, transport))
399+
lg.out(_DebugLevel, ' wrote %d bytes to %s/%s at %r' % (len(response_raw_data), route_id, transport_direction, transport))
400400
return True
401401
call_id = json_data.get('call_id')
402402
if call_id or (cmd in (
@@ -410,15 +410,28 @@ def do_process_incoming_message(transport, json_data, raw_data):
410410
)):
411411
route_info = routes(route_id)
412412
if _Debug:
413-
lg.args(_DebugLevel, direction=direction, route_info=route_info)
413+
lg.args(_DebugLevel, direction=transport_direction, route_info=route_info)
414414
if not route_info:
415415
lg.warn('route info for %r was not found' % route_id)
416416
return False
417-
if direction == 'external':
418-
internal_transport = route_info.get('internal_transport')
417+
external_transport = route_info.get('external_transport')
418+
internal_transport = route_info.get('internal_transport')
419+
if transport_direction == 'external':
419420
if not internal_transport:
421+
if not external_transport:
422+
lg.warn('internal and external transport for route %r are both disconnected' % route_id)
423+
return False
420424
lg.warn('internal transport for route %r is not connected' % route_id)
421-
return False
425+
json_response = {
426+
'cmd': 'server-disconnected',
427+
}
428+
response_raw_data = serialization.DictToBytes(json_response, encoding='utf-8')
429+
try:
430+
transport.write(response_raw_data)
431+
except:
432+
lg.exc()
433+
return False
434+
return True
422435
try:
423436
internal_transport.write(raw_data)
424437
except:
@@ -427,11 +440,22 @@ def do_process_incoming_message(transport, json_data, raw_data):
427440
if _Debug:
428441
lg.out(_DebugLevel, ' wrote %d bytes to %s/%s at %r' % (len(raw_data), route_id, 'internal', internal_transport))
429442
return True
430-
if direction == 'internal':
431-
external_transport = route_info.get('external_transport')
443+
if transport_direction == 'internal':
432444
if not external_transport:
445+
if not internal_transport:
446+
lg.warn('external and internal transport for route %r are both disconnected' % route_id)
447+
return False
433448
lg.warn('external transport for route %r is not connected' % route_id)
434-
return False
449+
json_response = {
450+
'cmd': 'client-disconnected',
451+
}
452+
response_raw_data = serialization.DictToBytes(json_response, encoding='utf-8')
453+
try:
454+
transport.write(response_raw_data)
455+
except:
456+
lg.exc()
457+
return False
458+
return True
435459
try:
436460
external_transport.write(raw_data)
437461
except:
@@ -440,5 +464,5 @@ def do_process_incoming_message(transport, json_data, raw_data):
440464
if _Debug:
441465
lg.out(_DebugLevel, ' wrote %d bytes to %s/%s at %r' % (len(raw_data), route_id, 'external', external_transport))
442466
return True
443-
lg.warn('unexpected direction: %r' % direction)
467+
lg.warn('unexpected direction: %r' % transport_direction)
444468
return False

0 commit comments

Comments
 (0)