0
# Namespace Classes
1
2
Class-based event handlers that organize Socket.IO communication into logical namespaces. Namespaces enable modular application design by separating different functional areas and providing inheritance-based event handling patterns.
3
4
## Capabilities
5
6
### Namespace
7
8
Server-side base class for creating class-based event handlers in synchronous applications. Provides method-based event handling and access to server functionality through inheritance.
9
10
```python { .api }
11
class Namespace:
12
"""
13
Base class for server-side class-based namespaces (synchronous).
14
15
Inherits from: BaseServerNamespace
16
17
Attributes:
18
namespace (str): Namespace path (default: '/')
19
server: Reference to the Socket.IO server instance
20
"""
21
22
def __init__(self, namespace='/'):
23
"""
24
Initialize the namespace.
25
26
Args:
27
namespace (str): Namespace path (default: '/')
28
"""
29
30
def trigger_event(self, event, *args):
31
"""
32
Dispatch events to handler methods.
33
34
Args:
35
event (str): Event name
36
*args: Event arguments
37
38
Returns:
39
Handler method return value
40
"""
41
42
def emit(self, event, data=None, to=None, room=None, skip_sid=None, namespace=None, callback=None):
43
"""
44
Emit an event to connected clients.
45
46
Args:
47
event (str): Event name
48
data: Event data to send
49
to (str or list): Target client session ID(s)
50
room (str or list): Target room name(s)
51
skip_sid (str): Skip this client session ID
52
namespace (str): Target namespace (defaults to this namespace)
53
callback (callable): Callback function for response
54
"""
55
56
def send(self, data, to=None, room=None, skip_sid=None, namespace=None, callback=None):
57
"""
58
Send a message event to connected clients.
59
60
Args:
61
data: Message data to send
62
to (str or list): Target client session ID(s)
63
room (str or list): Target room name(s)
64
skip_sid (str): Skip this client session ID
65
namespace (str): Target namespace (defaults to this namespace)
66
callback (callable): Callback function for response
67
"""
68
69
def call(self, event, data=None, to=None, sid=None, namespace=None, timeout=60):
70
"""
71
Emit an event and wait for a response from a specific client.
72
73
Args:
74
event (str): Event name
75
data: Event data to send
76
to (str): Target client session ID (deprecated, use sid)
77
sid (str): Target client session ID
78
namespace (str): Target namespace (defaults to this namespace)
79
timeout (int): Response timeout in seconds
80
81
Returns:
82
Response data from client
83
84
Raises:
85
TimeoutError: No response received within timeout
86
"""
87
88
def enter_room(self, sid, room, namespace=None):
89
"""
90
Add a client to a room.
91
92
Args:
93
sid (str): Client session ID
94
room (str): Room name
95
namespace (str): Target namespace (defaults to this namespace)
96
"""
97
98
def leave_room(self, sid, room, namespace=None):
99
"""
100
Remove a client from a room.
101
102
Args:
103
sid (str): Client session ID
104
room (str): Room name
105
namespace (str): Target namespace (defaults to this namespace)
106
"""
107
108
def close_room(self, room, namespace=None):
109
"""
110
Remove all clients from a room and delete the room.
111
112
Args:
113
room (str): Room name
114
namespace (str): Target namespace (defaults to this namespace)
115
"""
116
117
def rooms(self, sid, namespace=None):
118
"""
119
Get the list of rooms a client has joined.
120
121
Args:
122
sid (str): Client session ID
123
namespace (str): Target namespace (defaults to this namespace)
124
125
Returns:
126
list: Room names the client has joined
127
"""
128
129
def get_session(self, sid, namespace=None):
130
"""
131
Get the session data for a client.
132
133
Args:
134
sid (str): Client session ID
135
namespace (str): Target namespace (defaults to this namespace)
136
137
Returns:
138
dict: Session data
139
"""
140
141
def save_session(self, sid, session, namespace=None):
142
"""
143
Save session data for a client.
144
145
Args:
146
sid (str): Client session ID
147
session (dict): Session data to save
148
namespace (str): Target namespace (defaults to this namespace)
149
"""
150
151
def session(self, sid, namespace=None):
152
"""
153
Access client session data with context manager.
154
155
Args:
156
sid (str): Client session ID
157
namespace (str): Target namespace (defaults to this namespace)
158
159
Returns:
160
Context manager for session access
161
"""
162
163
def disconnect(self, sid, namespace=None):
164
"""
165
Disconnect a client.
166
167
Args:
168
sid (str): Client session ID
169
namespace (str): Target namespace (defaults to this namespace)
170
"""
171
172
# Event handler methods (override in subclass)
173
def on_connect(self, sid, environ):
174
"""
175
Called when a client connects.
176
177
Args:
178
sid (str): Client session ID
179
environ (dict): WSGI environ dictionary
180
"""
181
pass
182
183
def on_disconnect(self, sid):
184
"""
185
Called when a client disconnects.
186
187
Args:
188
sid (str): Client session ID
189
"""
190
pass
191
192
def on_message(self, sid, data):
193
"""
194
Called when a client sends a message event.
195
196
Args:
197
sid (str): Client session ID
198
data: Message data
199
"""
200
pass
201
```
202
203
#### Usage Example
204
205
```python
206
import socketio
207
208
class ChatNamespace(socketio.Namespace):
209
def on_connect(self, sid, environ):
210
print(f'Client {sid} connected to chat namespace')
211
self.enter_room(sid, 'lobby')
212
self.emit('welcome', {'message': 'Welcome to chat!'}, room=sid)
213
214
def on_disconnect(self, sid):
215
print(f'Client {sid} disconnected from chat')
216
217
def on_join_room(self, sid, data):
218
room = data['room']
219
self.enter_room(sid, room)
220
self.emit('status', {'message': f'Joined {room}'}, room=sid)
221
self.emit('user_joined', {'sid': sid}, room=room, skip_sid=sid)
222
223
def on_leave_room(self, sid, data):
224
room = data['room']
225
self.leave_room(sid, room)
226
self.emit('user_left', {'sid': sid}, room=room)
227
228
def on_chat_message(self, sid, data):
229
# Get user info from session
230
with self.session(sid) as session:
231
username = session.get('username', 'Anonymous')
232
233
room = data.get('room', 'lobby')
234
message = {
235
'username': username,
236
'message': data['message'],
237
'timestamp': time.time()
238
}
239
240
# Broadcast to room
241
self.emit('message', message, room=room)
242
243
def on_set_username(self, sid, data):
244
with self.session(sid) as session:
245
session['username'] = data['username']
246
247
self.emit('username_set', {'success': True}, room=sid)
248
249
class GameNamespace(socketio.Namespace):
250
def __init__(self):
251
super().__init__('/game')
252
self.games = {}
253
254
def on_connect(self, sid, environ):
255
print(f'Player {sid} connected to game namespace')
256
257
def on_create_game(self, sid, data):
258
game_id = data['game_id']
259
self.games[game_id] = {'players': [sid], 'status': 'waiting'}
260
self.enter_room(sid, game_id)
261
self.emit('game_created', {'game_id': game_id}, room=sid)
262
263
def on_join_game(self, sid, data):
264
game_id = data['game_id']
265
if game_id in self.games:
266
self.games[game_id]['players'].append(sid)
267
self.enter_room(sid, game_id)
268
self.emit('player_joined', {'sid': sid}, room=game_id)
269
270
# Start game if enough players
271
if len(self.games[game_id]['players']) >= 2:
272
self.games[game_id]['status'] = 'playing'
273
self.emit('game_started', room=game_id)
274
275
# Register namespaces with server
276
sio = socketio.Server()
277
sio.register_namespace(ChatNamespace('/chat'))
278
sio.register_namespace(GameNamespace())
279
```
280
281
### AsyncNamespace
282
283
Asynchronous version of the Namespace class for server-side class-based event handlers in asyncio applications.
284
285
```python { .api }
286
class AsyncNamespace:
287
"""
288
Base class for asyncio server-side class-based namespaces.
289
290
Inherits from: BaseServerNamespace
291
292
Attributes:
293
namespace (str): Namespace path (default: '/')
294
server: Reference to the AsyncServer instance
295
"""
296
297
def __init__(self, namespace='/'):
298
"""
299
Initialize the async namespace.
300
301
Args:
302
namespace (str): Namespace path (default: '/')
303
"""
304
305
async def trigger_event(self, event, *args):
306
"""
307
Dispatch events to async handler methods.
308
309
Args:
310
event (str): Event name
311
*args: Event arguments
312
313
Returns:
314
Handler method return value
315
"""
316
317
async def emit(self, event, data=None, to=None, room=None, skip_sid=None, namespace=None, callback=None):
318
"""
319
Emit an event to connected clients.
320
321
Args:
322
event (str): Event name
323
data: Event data to send
324
to (str or list): Target client session ID(s)
325
room (str or list): Target room name(s)
326
skip_sid (str): Skip this client session ID
327
namespace (str): Target namespace (defaults to this namespace)
328
callback (coroutine): Async callback function for response
329
"""
330
331
async def send(self, data, to=None, room=None, skip_sid=None, namespace=None, callback=None):
332
"""
333
Send a message event to connected clients.
334
335
Args:
336
data: Message data to send
337
to (str or list): Target client session ID(s)
338
room (str or list): Target room name(s)
339
skip_sid (str): Skip this client session ID
340
namespace (str): Target namespace (defaults to this namespace)
341
callback (coroutine): Async callback function for response
342
"""
343
344
async def call(self, event, data=None, to=None, sid=None, namespace=None, timeout=60):
345
"""
346
Emit an event and wait for a response from a specific client.
347
348
Args:
349
event (str): Event name
350
data: Event data to send
351
to (str): Target client session ID (deprecated, use sid)
352
sid (str): Target client session ID
353
namespace (str): Target namespace (defaults to this namespace)
354
timeout (int): Response timeout in seconds
355
356
Returns:
357
Response data from client
358
359
Raises:
360
TimeoutError: No response received within timeout
361
"""
362
363
async def enter_room(self, sid, room, namespace=None):
364
"""
365
Add a client to a room.
366
367
Args:
368
sid (str): Client session ID
369
room (str): Room name
370
namespace (str): Target namespace (defaults to this namespace)
371
"""
372
373
async def leave_room(self, sid, room, namespace=None):
374
"""
375
Remove a client from a room.
376
377
Args:
378
sid (str): Client session ID
379
room (str): Room name
380
namespace (str): Target namespace (defaults to this namespace)
381
"""
382
383
async def close_room(self, room, namespace=None):
384
"""
385
Remove all clients from a room and delete the room.
386
387
Args:
388
room (str): Room name
389
namespace (str): Target namespace (defaults to this namespace)
390
"""
391
392
async def rooms(self, sid, namespace=None):
393
"""
394
Get the list of rooms a client has joined.
395
396
Args:
397
sid (str): Client session ID
398
namespace (str): Target namespace (defaults to this namespace)
399
400
Returns:
401
list: Room names the client has joined
402
"""
403
404
async def get_session(self, sid, namespace=None):
405
"""
406
Get the session data for a client.
407
408
Args:
409
sid (str): Client session ID
410
namespace (str): Target namespace (defaults to this namespace)
411
412
Returns:
413
dict: Session data
414
"""
415
416
async def save_session(self, sid, session, namespace=None):
417
"""
418
Save session data for a client.
419
420
Args:
421
sid (str): Client session ID
422
session (dict): Session data to save
423
namespace (str): Target namespace (defaults to this namespace)
424
"""
425
426
def session(self, sid, namespace=None):
427
"""
428
Access client session data with async context manager.
429
430
Args:
431
sid (str): Client session ID
432
namespace (str): Target namespace (defaults to this namespace)
433
434
Returns:
435
Async context manager for session access
436
"""
437
438
async def disconnect(self, sid, namespace=None):
439
"""
440
Disconnect a client.
441
442
Args:
443
sid (str): Client session ID
444
namespace (str): Target namespace (defaults to this namespace)
445
"""
446
447
# Async event handler methods (override in subclass)
448
async def on_connect(self, sid, environ):
449
"""
450
Called when a client connects.
451
452
Args:
453
sid (str): Client session ID
454
environ (dict): WSGI environ dictionary
455
"""
456
pass
457
458
async def on_disconnect(self, sid):
459
"""
460
Called when a client disconnects.
461
462
Args:
463
sid (str): Client session ID
464
"""
465
pass
466
467
async def on_message(self, sid, data):
468
"""
469
Called when a client sends a message event.
470
471
Args:
472
sid (str): Client session ID
473
data: Message data
474
"""
475
pass
476
```
477
478
#### Usage Example
479
480
```python
481
import asyncio
482
import socketio
483
484
class AsyncChatNamespace(socketio.AsyncNamespace):
485
def __init__(self):
486
super().__init__('/chat')
487
self.user_cache = {}
488
489
async def on_connect(self, sid, environ):
490
print(f'Client {sid} connected to async chat namespace')
491
await self.enter_room(sid, 'lobby')
492
await self.emit('welcome', {'message': 'Welcome!'}, room=sid)
493
494
async def on_disconnect(self, sid):
495
print(f'Client {sid} disconnected from async chat')
496
# Clean up user cache
497
if sid in self.user_cache:
498
del self.user_cache[sid]
499
500
async def on_join_room(self, sid, data):
501
room = data['room']
502
await self.enter_room(sid, room)
503
await self.emit('status', {'message': f'Joined {room}'}, room=sid)
504
await self.emit('user_joined', {'sid': sid}, room=room, skip_sid=sid)
505
506
async def on_chat_message(self, sid, data):
507
# Async session access
508
async with self.session(sid) as session:
509
username = session.get('username', 'Anonymous')
510
511
# Simulate async processing (e.g., content filtering)
512
await asyncio.sleep(0.01)
513
514
room = data.get('room', 'lobby')
515
message = {
516
'username': username,
517
'message': data['message'],
518
'timestamp': time.time()
519
}
520
521
# Broadcast to room
522
await self.emit('message', message, room=room)
523
524
async def on_get_user_info(self, sid, data):
525
# Simulate async database lookup
526
user_id = data['user_id']
527
user_info = await self.fetch_user_info(user_id)
528
return {'user_info': user_info}
529
530
async def fetch_user_info(self, user_id):
531
# Simulate async database call
532
await asyncio.sleep(0.1)
533
return {'id': user_id, 'name': f'User {user_id}', 'status': 'online'}
534
535
class AsyncGameNamespace(socketio.AsyncNamespace):
536
def __init__(self):
537
super().__init__('/game')
538
self.games = {}
539
self.game_lock = asyncio.Lock()
540
541
async def on_connect(self, sid, environ):
542
print(f'Player {sid} connected to async game namespace')
543
544
async def on_create_game(self, sid, data):
545
game_id = data['game_id']
546
547
async with self.game_lock:
548
self.games[game_id] = {
549
'players': [sid],
550
'status': 'waiting',
551
'created_at': time.time()
552
}
553
554
await self.enter_room(sid, game_id)
555
await self.emit('game_created', {'game_id': game_id}, room=sid)
556
557
async def on_join_game(self, sid, data):
558
game_id = data['game_id']
559
560
async with self.game_lock:
561
if game_id in self.games:
562
self.games[game_id]['players'].append(sid)
563
await self.enter_room(sid, game_id)
564
await self.emit('player_joined', {'sid': sid}, room=game_id)
565
566
# Start game if enough players
567
if len(self.games[game_id]['players']) >= 2:
568
self.games[game_id]['status'] = 'playing'
569
await self.emit('game_started', room=game_id)
570
571
# Start game logic asynchronously
572
asyncio.create_task(self.run_game(game_id))
573
574
async def run_game(self, game_id):
575
# Simulate async game logic
576
await asyncio.sleep(1)
577
await self.emit('game_update', {'status': 'running'}, room=game_id)
578
579
# Register namespaces with async server
580
sio = socketio.AsyncServer()
581
sio.register_namespace(AsyncChatNamespace())
582
sio.register_namespace(AsyncGameNamespace())
583
```
584
585
### ClientNamespace
586
587
Base class for client-side class-based event handlers in synchronous client applications.
588
589
```python { .api }
590
class ClientNamespace:
591
"""
592
Base class for client-side class-based namespaces (synchronous).
593
594
Inherits from: BaseClientNamespace
595
596
Attributes:
597
namespace (str): Namespace path (default: '/')
598
client: Reference to the Client instance
599
"""
600
601
def __init__(self, namespace='/'):
602
"""
603
Initialize the client namespace.
604
605
Args:
606
namespace (str): Namespace path (default: '/')
607
"""
608
609
def trigger_event(self, event, *args):
610
"""
611
Dispatch events to handler methods.
612
613
Args:
614
event (str): Event name
615
*args: Event arguments
616
617
Returns:
618
Handler method return value
619
"""
620
621
def emit(self, event, data=None, namespace=None, callback=None):
622
"""
623
Emit an event to the server.
624
625
Args:
626
event (str): Event name
627
data: Event data to send
628
namespace (str): Target namespace (defaults to this namespace)
629
callback (callable): Callback function for response
630
"""
631
632
def send(self, data, namespace=None, callback=None):
633
"""
634
Send a message event to the server.
635
636
Args:
637
data: Message data to send
638
namespace (str): Target namespace (defaults to this namespace)
639
callback (callable): Callback function for response
640
"""
641
642
def call(self, event, data=None, namespace=None, timeout=60):
643
"""
644
Emit an event and wait for a response from the server.
645
646
Args:
647
event (str): Event name
648
data: Event data to send
649
namespace (str): Target namespace (defaults to this namespace)
650
timeout (int): Response timeout in seconds
651
652
Returns:
653
Response data from server
654
655
Raises:
656
TimeoutError: No response received within timeout
657
"""
658
659
def disconnect(self):
660
"""
661
Disconnect from the server.
662
"""
663
664
# Event handler methods (override in subclass)
665
def on_connect(self):
666
"""Called when connected to the server."""
667
pass
668
669
def on_disconnect(self):
670
"""Called when disconnected from the server."""
671
pass
672
673
def on_message(self, data):
674
"""Called when receiving a message event from the server."""
675
pass
676
```
677
678
#### Usage Example
679
680
```python
681
import socketio
682
683
class ChatClientNamespace(socketio.ClientNamespace):
684
def __init__(self):
685
super().__init__('/chat')
686
self.username = None
687
688
def on_connect(self):
689
print('Connected to chat namespace')
690
self.emit('set_username', {'username': 'Alice'})
691
692
def on_disconnect(self):
693
print('Disconnected from chat namespace')
694
695
def on_welcome(self, data):
696
print(f'Welcome message: {data["message"]}')
697
698
def on_message(self, data):
699
print(f'{data["username"]}: {data["message"]}')
700
701
def on_username_set(self, data):
702
if data['success']:
703
print('Username set successfully')
704
self.emit('join_room', {'room': 'general'})
705
706
def send_message(self, message, room='general'):
707
self.emit('chat_message', {
708
'message': message,
709
'room': room
710
})
711
712
# Use with client
713
sio = socketio.Client()
714
chat_ns = ChatClientNamespace()
715
sio.register_namespace(chat_ns)
716
717
sio.connect('http://localhost:5000')
718
719
# Send messages through namespace
720
chat_ns.send_message('Hello everyone!')
721
722
sio.wait()
723
```
724
725
### AsyncClientNamespace
726
727
Asynchronous version of ClientNamespace for client-side class-based event handlers in asyncio client applications.
728
729
```python { .api }
730
class AsyncClientNamespace:
731
"""
732
Base class for asyncio client-side class-based namespaces.
733
734
Inherits from: BaseClientNamespace
735
736
Attributes:
737
namespace (str): Namespace path (default: '/')
738
client: Reference to the AsyncClient instance
739
"""
740
741
def __init__(self, namespace='/'):
742
"""
743
Initialize the async client namespace.
744
745
Args:
746
namespace (str): Namespace path (default: '/')
747
"""
748
749
async def trigger_event(self, event, *args):
750
"""
751
Dispatch events to async handler methods.
752
753
Args:
754
event (str): Event name
755
*args: Event arguments
756
757
Returns:
758
Handler method return value
759
"""
760
761
async def emit(self, event, data=None, namespace=None, callback=None):
762
"""
763
Emit an event to the server.
764
765
Args:
766
event (str): Event name
767
data: Event data to send
768
namespace (str): Target namespace (defaults to this namespace)
769
callback (coroutine): Async callback function for response
770
"""
771
772
async def send(self, data, namespace=None, callback=None):
773
"""
774
Send a message event to the server.
775
776
Args:
777
data: Message data to send
778
namespace (str): Target namespace (defaults to this namespace)
779
callback (coroutine): Async callback function for response
780
"""
781
782
async def call(self, event, data=None, namespace=None, timeout=60):
783
"""
784
Emit an event and wait for a response from the server.
785
786
Args:
787
event (str): Event name
788
data: Event data to send
789
namespace (str): Target namespace (defaults to this namespace)
790
timeout (int): Response timeout in seconds
791
792
Returns:
793
Response data from server
794
795
Raises:
796
TimeoutError: No response received within timeout
797
"""
798
799
async def disconnect(self):
800
"""
801
Disconnect from the server.
802
"""
803
804
# Async event handler methods (override in subclass)
805
async def on_connect(self):
806
"""Called when connected to the server."""
807
pass
808
809
async def on_disconnect(self):
810
"""Called when disconnected from the server."""
811
pass
812
813
async def on_message(self, data):
814
"""Called when receiving a message event from the server."""
815
pass
816
```
817
818
#### Usage Example
819
820
```python
821
import asyncio
822
import socketio
823
824
class AsyncChatClientNamespace(socketio.AsyncClientNamespace):
825
def __init__(self):
826
super().__init__('/chat')
827
self.message_queue = asyncio.Queue()
828
829
async def on_connect(self):
830
print('Connected to async chat namespace')
831
await self.emit('set_username', {'username': 'Bob'})
832
833
async def on_disconnect(self):
834
print('Disconnected from async chat namespace')
835
836
async def on_welcome(self, data):
837
print(f'Welcome message: {data["message"]}')
838
839
async def on_message(self, data):
840
print(f'{data["username"]}: {data["message"]}')
841
# Add to processing queue
842
await self.message_queue.put(data)
843
844
async def on_username_set(self, data):
845
if data['success']:
846
print('Username set successfully')
847
await self.emit('join_room', {'room': 'general'})
848
849
async def send_message(self, message, room='general'):
850
await self.emit('chat_message', {
851
'message': message,
852
'room': room
853
})
854
855
async def process_messages(self):
856
"""Background task to process incoming messages"""
857
while True:
858
try:
859
message = await asyncio.wait_for(
860
self.message_queue.get(), timeout=1.0
861
)
862
# Process message asynchronously
863
await self.handle_message(message)
864
except asyncio.TimeoutError:
865
continue
866
867
async def handle_message(self, message):
868
# Simulate async message processing
869
await asyncio.sleep(0.1)
870
print(f'Processed message from {message["username"]}')
871
872
async def main():
873
sio = socketio.AsyncClient()
874
chat_ns = AsyncChatClientNamespace()
875
sio.register_namespace(chat_ns)
876
877
await sio.connect('http://localhost:5000')
878
879
# Start message processing task
880
process_task = asyncio.create_task(chat_ns.process_messages())
881
882
# Send some messages
883
await chat_ns.send_message('Hello async world!')
884
await asyncio.sleep(1)
885
await chat_ns.send_message('How is everyone?')
886
887
# Wait for events
888
await sio.wait()
889
890
# Run the async client
891
asyncio.run(main())
892
```
893
894
## Namespace Registration
895
896
Namespaces must be registered with their respective servers or clients:
897
898
```python
899
# Server namespace registration
900
sio = socketio.Server()
901
sio.register_namespace(ChatNamespace('/chat'))
902
sio.register_namespace(GameNamespace('/game'))
903
904
# Client namespace registration
905
client = socketio.Client()
906
client.register_namespace(ChatClientNamespace('/chat'))
907
client.register_namespace(GameClientNamespace('/game'))
908
909
# Async server namespace registration
910
async_sio = socketio.AsyncServer()
911
async_sio.register_namespace(AsyncChatNamespace('/chat'))
912
913
# Async client namespace registration
914
async_client = socketio.AsyncClient()
915
async_client.register_namespace(AsyncChatClientNamespace('/chat'))
916
```