@@ -124,7 +124,7 @@ def __init__(self, reconnection=True, reconnection_attempts=0,
124124 self .sid = None
125125
126126 self .connected = False
127- self .namespaces = []
127+ self .namespaces = {}
128128 self .handlers = {}
129129 self .namespace_handlers = {}
130130 self .callbacks = {}
@@ -242,14 +242,17 @@ def connect(self, url, headers={}, transports=None,
242242 are ``'polling'`` and ``'websocket'``. If not
243243 given, the polling transport is connected first,
244244 then an upgrade to websocket is attempted.
245- :param namespaces: The list of custom namespaces to connect, in
246- addition to the default namespace. If not given,
247- the namespace list is obtained from the registered
248- event handlers.
245+ :param namespaces: The namespaces to connect as a string or list of
246+ strings. If not given, the namespaces that have
247+ registered event handlers are connected.
249248 :param socketio_path: The endpoint where the Socket.IO server is
250249 installed. The default value is appropriate for
251250 most cases.
252251
252+ Note: The connection mechannism occurs in the background and will
253+ complete at some point after this function returns. The connection
254+ will be established when the ``connect`` event is invoked.
255+
253256 Example usage::
254257
255258 sio = socketio.Client()
@@ -266,8 +269,7 @@ def connect(self, url, headers={}, transports=None,
266269 set (self .namespace_handlers .keys ()))
267270 elif isinstance (namespaces , six .string_types ):
268271 namespaces = [namespaces ]
269- self .connection_namespaces = namespaces
270- self .namespaces = [n for n in namespaces if n != '/' ]
272+ self .connection_namespaces = namespaces
271273 try :
272274 self .eio .connect (url , headers = headers , transports = transports ,
273275 engineio_path = socketio_path )
@@ -318,7 +320,7 @@ def emit(self, event, data=None, namespace=None, callback=None):
318320 situation.
319321 """
320322 namespace = namespace or '/'
321- if namespace != '/' and namespace not in self .namespaces :
323+ if namespace not in self .namespaces :
322324 raise exceptions .BadNamespaceError (
323325 namespace + ' is not a connected namespace.' )
324326 self .logger .info ('Emitting event "%s" [%s]' , event , namespace )
@@ -402,11 +404,23 @@ def disconnect(self):
402404 # later in _handle_eio_disconnect we invoke the disconnect handler
403405 for n in self .namespaces :
404406 self ._send_packet (packet .Packet (packet .DISCONNECT , namespace = n ))
405- self ._send_packet (packet .Packet (
406- packet .DISCONNECT , namespace = '/' ))
407407 self .connected = False
408408 self .eio .disconnect (abort = True )
409409
410+ def get_sid (self , namespace = None ):
411+ """Return the ``sid`` associated with a connection.
412+
413+ :param namespace: The Socket.IO namespace. If this argument is omitted
414+ the handler is associated with the default
415+ namespace. Note that unlike previous versions, the
416+ current version of the Socket.IO protocol uses
417+ different ``sid`` values per namespace.
418+
419+ This method returns the ``sid`` for the requested namespace as a
420+ string.
421+ """
422+ return self .namespaces .get (namespace or '/' )
423+
410424 def transport (self ):
411425 """Return the name of the transport used by the client.
412426
@@ -460,29 +474,22 @@ def _generate_ack_id(self, namespace, callback):
460474 self .callbacks [namespace ][id ] = callback
461475 return id
462476
463- def _handle_connect (self , namespace ):
477+ def _handle_connect (self , namespace , data ):
464478 namespace = namespace or '/'
465479 self .logger .info ('Namespace {} is connected' .format (namespace ))
480+ if namespace not in self .namespaces :
481+ self .namespaces [namespace ] = (data or {}).get ('sid' , self .sid )
466482 self ._trigger_event ('connect' , namespace = namespace )
467- if namespace == '/' :
468- for n in self .namespaces :
469- self ._send_packet (packet .Packet (packet .CONNECT , namespace = n ))
470- elif namespace not in self .namespaces :
471- self .namespaces .append (namespace )
472483
473484 def _handle_disconnect (self , namespace ):
474485 if not self .connected :
475486 return
476487 namespace = namespace or '/'
477- if namespace == '/' :
478- for n in self .namespaces :
479- self ._trigger_event ('disconnect' , namespace = n )
480- self .namespaces = []
481488 self ._trigger_event ('disconnect' , namespace = namespace )
482489 if namespace in self .namespaces :
483- self .namespaces . remove ( namespace )
484- if namespace == '/' :
485- self .connected = False
490+ del self .namespaces [ namespace ]
491+ if not self . namespaces :
492+ self .eio . disconnect ( abort = True )
486493
487494 def _handle_event (self , namespace , id , data ):
488495 namespace = namespace or '/'
@@ -524,7 +531,7 @@ def _handle_error(self, namespace, data):
524531 data = (data ,)
525532 self ._trigger_event ('connect_error' , namespace , * data )
526533 if namespace in self .namespaces :
527- self .namespaces . remove ( namespace )
534+ del self .namespaces [ namespace ]
528535 if namespace == '/' :
529536 self .namespaces = []
530537 self .connected = False
@@ -581,6 +588,8 @@ def _handle_eio_connect(self):
581588 """Handle the Engine.IO connection event."""
582589 self .logger .info ('Engine.IO connection established' )
583590 self .sid = self .eio .sid
591+ for n in self .connection_namespaces :
592+ self ._send_packet (packet .Packet (packet .CONNECT , namespace = n ))
584593
585594 def _handle_eio_message (self , data ):
586595 """Dispatch Engine.IO messages."""
@@ -595,7 +604,7 @@ def _handle_eio_message(self, data):
595604 else :
596605 pkt = packet .Packet (encoded_packet = data )
597606 if pkt .packet_type == packet .CONNECT :
598- self ._handle_connect (pkt .namespace )
607+ self ._handle_connect (pkt .namespace , pkt . data )
599608 elif pkt .packet_type == packet .DISCONNECT :
600609 self ._handle_disconnect (pkt .namespace )
601610 elif pkt .packet_type == packet .EVENT :
@@ -616,7 +625,6 @@ def _handle_eio_disconnect(self):
616625 if self .connected :
617626 for n in self .namespaces :
618627 self ._trigger_event ('disconnect' , namespace = n )
619- self ._trigger_event ('disconnect' , namespace = '/' )
620628 self .namespaces = []
621629 self .connected = False
622630 self .callbacks = {}
0 commit comments