From 79e1adb0de715f307fb9858cf568e8a8d1206f51 Mon Sep 17 00:00:00 2001 From: Pavel Mikhalkevich Date: Sat, 17 Aug 2024 21:27:03 +0400 Subject: [PATCH 1/4] Enable emitting to single client in AsyncPubSubManager --- src/socketio/async_pubsub_manager.py | 3 ++- tests/async/test_pubsub_manager.py | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/socketio/async_pubsub_manager.py b/src/socketio/async_pubsub_manager.py index 3e11f1ea..72946eb2 100644 --- a/src/socketio/async_pubsub_manager.py +++ b/src/socketio/async_pubsub_manager.py @@ -38,7 +38,7 @@ def initialize(self): self._get_logger().info(self.name + ' backend initialized.') async def emit(self, event, data, namespace=None, room=None, skip_sid=None, - callback=None, **kwargs): + callback=None, to=None, **kwargs): """Emit a message to a single client, a room, or all the clients connected to the namespace. @@ -49,6 +49,7 @@ async def emit(self, event, data, namespace=None, room=None, skip_sid=None, Note: this method is a coroutine. """ + room = to or room if kwargs.get('ignore_queue'): return await super().emit( event, data, namespace=namespace, room=room, skip_sid=skip_sid, diff --git a/tests/async/test_pubsub_manager.py b/tests/async/test_pubsub_manager.py index 28812992..c7758fa9 100644 --- a/tests/async/test_pubsub_manager.py +++ b/tests/async/test_pubsub_manager.py @@ -67,6 +67,23 @@ def test_emit(self): } ) + def test_emit_single_client(self): + sid = 'room-mate' + _run(self.pm.emit('foo', 'bar', to=sid)) + self.pm._publish.mock.assert_called_once_with( + { + 'method': 'emit', + 'event': 'foo', + 'data': 'bar', + 'namespace': '/', + 'room': sid, + 'skip_sid': None, + 'callback': None, + 'host_id': '123456', + } + ) + + def test_emit_with_namespace(self): _run(self.pm.emit('foo', 'bar', namespace='/baz')) self.pm._publish.mock.assert_called_once_with( From d5246982b95865b09d17864a937465d9de0b90f7 Mon Sep 17 00:00:00 2001 From: Pavel Mikhalkevich Date: Sun, 18 Aug 2024 10:34:41 +0400 Subject: [PATCH 2/4] Handle `to` in async manager and sync versions --- src/socketio/async_manager.py | 3 ++- src/socketio/manager.py | 3 ++- src/socketio/pubsub_manager.py | 3 ++- tests/async/test_manager.py | 2 +- tests/common/test_manager.py | 2 +- tests/common/test_pubsub_manager.py | 16 ++++++++++++++++ 6 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/socketio/async_manager.py b/src/socketio/async_manager.py index dcf79cf8..47e7a79f 100644 --- a/src/socketio/async_manager.py +++ b/src/socketio/async_manager.py @@ -11,12 +11,13 @@ async def can_disconnect(self, sid, namespace): return self.is_connected(sid, namespace) async def emit(self, event, data, namespace, room=None, skip_sid=None, - callback=None, **kwargs): + callback=None, to=None, **kwargs): """Emit a message to a single client, a room, or all the clients connected to the namespace. Note: this method is a coroutine. """ + room = to or room if namespace not in self.rooms: return if isinstance(data, tuple): diff --git a/src/socketio/manager.py b/src/socketio/manager.py index 813c4af9..3ebf6768 100644 --- a/src/socketio/manager.py +++ b/src/socketio/manager.py @@ -20,9 +20,10 @@ def can_disconnect(self, sid, namespace): return self.is_connected(sid, namespace) def emit(self, event, data, namespace, room=None, skip_sid=None, - callback=None, **kwargs): + callback=None, to=None, **kwargs): """Emit a message to a single client, a room, or all the clients connected to the namespace.""" + room = to or room if namespace not in self.rooms: return if isinstance(data, tuple): diff --git a/src/socketio/pubsub_manager.py b/src/socketio/pubsub_manager.py index 5ca7619c..3270b4cb 100644 --- a/src/socketio/pubsub_manager.py +++ b/src/socketio/pubsub_manager.py @@ -37,7 +37,7 @@ def initialize(self): self._get_logger().info(self.name + ' backend initialized.') def emit(self, event, data, namespace=None, room=None, skip_sid=None, - callback=None, **kwargs): + callback=None, to=None, **kwargs): """Emit a message to a single client, a room, or all the clients connected to the namespace. @@ -46,6 +46,7 @@ def emit(self, event, data, namespace=None, room=None, skip_sid=None, The parameters are the same as in :meth:`.Server.emit`. """ + room = to or room if kwargs.get('ignore_queue'): return super().emit( event, data, namespace=namespace, room=room, skip_sid=skip_sid, diff --git a/tests/async/test_manager.py b/tests/async/test_manager.py index 90d4ad1d..83f64752 100644 --- a/tests/async/test_manager.py +++ b/tests/async/test_manager.py @@ -205,7 +205,7 @@ def test_emit_to_sid(self): _run(self.bm.connect('456', '/foo')) _run( self.bm.emit( - 'my event', {'foo': 'bar'}, namespace='/foo', room=sid + 'my event', {'foo': 'bar'}, namespace='/foo', to=sid ) ) assert self.bm.server._send_eio_packet.mock.call_count == 1 diff --git a/tests/common/test_manager.py b/tests/common/test_manager.py index 8bb826a5..571d2fdc 100644 --- a/tests/common/test_manager.py +++ b/tests/common/test_manager.py @@ -206,7 +206,7 @@ def test_rooms(self): def test_emit_to_sid(self): sid = self.bm.connect('123', '/foo') self.bm.connect('456', '/foo') - self.bm.emit('my event', {'foo': 'bar'}, namespace='/foo', room=sid) + self.bm.emit('my event', {'foo': 'bar'}, namespace='/foo', to=sid) assert self.bm.server._send_eio_packet.call_count == 1 assert self.bm.server._send_eio_packet.call_args_list[0][0][0] == '123' pkt = self.bm.server._send_eio_packet.call_args_list[0][0][1] diff --git a/tests/common/test_pubsub_manager.py b/tests/common/test_pubsub_manager.py index 4e972149..5a4653ec 100644 --- a/tests/common/test_pubsub_manager.py +++ b/tests/common/test_pubsub_manager.py @@ -78,6 +78,22 @@ def test_emit(self): } ) + def test_emit_with_to(self): + sid = "ferris" + self.pm.emit('foo', 'bar', to=sid) + self.pm._publish.assert_called_once_with( + { + 'method': 'emit', + 'event': 'foo', + 'data': 'bar', + 'namespace': '/', + 'room': sid, + 'skip_sid': None, + 'callback': None, + 'host_id': '123456', + } + ) + def test_emit_with_namespace(self): self.pm.emit('foo', 'bar', namespace='/baz') self.pm._publish.assert_called_once_with( From 4716744bb96e42ba7f2832cf70a4f4f0ed0b16f3 Mon Sep 17 00:00:00 2001 From: Pavel Mikhalkevich Date: Sun, 18 Aug 2024 10:40:14 +0400 Subject: [PATCH 3/4] Name tests consistently --- tests/async/test_pubsub_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/async/test_pubsub_manager.py b/tests/async/test_pubsub_manager.py index c7758fa9..cd8a668d 100644 --- a/tests/async/test_pubsub_manager.py +++ b/tests/async/test_pubsub_manager.py @@ -67,7 +67,7 @@ def test_emit(self): } ) - def test_emit_single_client(self): + def test_emit_with_to(self): sid = 'room-mate' _run(self.pm.emit('foo', 'bar', to=sid)) self.pm._publish.mock.assert_called_once_with( From d21c739f2c295917a2d4ead04e777e04f0e68bb5 Mon Sep 17 00:00:00 2001 From: Pavel Mikhalkevich Date: Sun, 18 Aug 2024 20:33:15 +0400 Subject: [PATCH 4/4] Rm extra blank line in test_pubsub_manager --- tests/async/test_pubsub_manager.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/async/test_pubsub_manager.py b/tests/async/test_pubsub_manager.py index cd8a668d..c7aeb6e9 100644 --- a/tests/async/test_pubsub_manager.py +++ b/tests/async/test_pubsub_manager.py @@ -83,7 +83,6 @@ def test_emit_with_to(self): } ) - def test_emit_with_namespace(self): _run(self.pm.emit('foo', 'bar', namespace='/baz')) self.pm._publish.mock.assert_called_once_with(