From 5633917201825366771011e10d7a3df3d2dc8a75 Mon Sep 17 00:00:00 2001 From: Miguel Grinberg Date: Thu, 6 Aug 2015 00:35:57 -0700 Subject: [PATCH] added server disconnect support --- example/app.py | 8 +++++++- example/templates/index.html | 9 ++++++--- socketio/base_manager.py | 6 +++--- socketio/server.py | 17 +++++++++++++++++ tests/test_server.py | 15 +++++++++++++++ 5 files changed, 48 insertions(+), 7 deletions(-) diff --git a/example/app.py b/example/app.py index 59214ea1..74a42792 100755 --- a/example/app.py +++ b/example/app.py @@ -77,9 +77,15 @@ def send_room_message(sid, message): room=message['room'], namespace='/test') +@socketio.on('disconnect request', namespace='/test') +def disconnect_request(sid): + socketio.disconnect(sid, namespace='/test') + + @socketio.on('connect', namespace='/test') def test_connect(sid, environ): - socketio.emit('my response', {'data': 'Connected', 'count': 0}, room=sid) + socketio.emit('my response', {'data': 'Connected', 'count': 0}, room=sid, + namespace='/test') @socketio.on('disconnect', namespace='/test') diff --git a/example/templates/index.html b/example/templates/index.html index 8da7b13d..5c373408 100755 --- a/example/templates/index.html +++ b/example/templates/index.html @@ -9,12 +9,12 @@ namespace = '/test'; var socket = io.connect('http://' + document.domain + ':' + location.port + namespace); - socket.on('my response', function(msg) { - $('#log').append('
Received: ' + msg.data); - }); socket.on('connect', function() { socket.emit('my event', {data: 'I\'m connected!'}); }); + socket.on('my response', function(msg) { + $('#log').append('
Received: ' + msg.data); + }); // event handler for server sent data // the data is displayed in the "Received" section of the page @@ -79,6 +79,9 @@

Send:

+
+ +

Receive:

diff --git a/socketio/base_manager.py b/socketio/base_manager.py index 535137bc..8ba79251 100755 --- a/socketio/base_manager.py +++ b/socketio/base_manager.py @@ -27,14 +27,14 @@ def get_participants(self, namespace, room): self._clean_rooms() def connect(self, sid, namespace): - """Record a client connection to a namespace.""" + """Register a client connection to a namespace.""" self.enter_room(sid, namespace, None) self.enter_room(sid, namespace, sid) def disconnect(self, sid, namespace): - """Record a client disconnect event.""" + """Register a client disconnect event.""" if namespace == '/': - namespace_list = list(six.iterkeys(self.rooms)) + namespace_list = list(self.get_namespaces()) else: namespace_list = [namespace] for n in namespace_list: diff --git a/socketio/server.py b/socketio/server.py index 04f46d69..7fe7c1f5 100755 --- a/socketio/server.py +++ b/socketio/server.py @@ -246,6 +246,23 @@ def rooms(self, sid, namespace=None): namespace = namespace or '/' return self.manager.get_rooms(sid, namespace) + def disconnect(self, sid, namespace=None): + """Disconnect a client. + + :param sid: Session ID of the client. + :param namespace: The Socket.IO namespace to disconnect. If this + argument is omitted the default namespace is used. + """ + self.logger.info('Disconnecting %s]', sid) + if namespace is None or namespace == '/': + for namespace in self.manager.get_namespaces(): + self._send_packet(sid, packet.Packet(packet.DISCONNECT, + namespace=namespace)) + else: + self._send_packet(sid, packet.Packet(packet.DISCONNECT, + namespace=namespace)) + self.manager.disconnect(sid, namespace=namespace) + def handle_request(self, environ, start_response): """Handle an HTTP request from the client. diff --git a/tests/test_server.py b/tests/test_server.py index 968a07dd..460fabe4 100755 --- a/tests/test_server.py +++ b/tests/test_server.py @@ -345,6 +345,21 @@ def test_invalid_callback(self, eio): self.assertRaises(ValueError, s._handle_eio_message, '123', '32["foo",2]') + def test_disconnect_all(self, eio): + s = server.Server() + s._handle_eio_connect('123', 'environ') + s._handle_eio_message('123', '0/foo') + s.disconnect('123') + s.eio.send.assert_any_call('123', '1/foo', binary=False) + s.eio.send.assert_any_call('123', '1', binary=False) + + def test_disconnect_namespace(self, eio): + s = server.Server() + s._handle_eio_connect('123', 'environ') + s._handle_eio_message('123', '0/foo') + s.disconnect('123', namespace='/foo') + s.eio.send.assert_any_call('123', '1/foo', binary=False) + def test_logger(self, eio): s = server.Server(logger=False) self.assertEqual(s.logger.getEffectiveLevel(), logging.ERROR)