|
@ -8,7 +8,7 @@ socketio documentation |
|
|
|
|
|
|
|
|
:ref:`genindex` | :ref:`modindex` | :ref:`search` |
|
|
:ref:`genindex` | :ref:`modindex` | :ref:`search` |
|
|
|
|
|
|
|
|
This project implements an Socket.IO server that can run standalone or |
|
|
This project implements a Socket.IO server that can run standalone or |
|
|
integrated with a Python WSGI application. The following are some of its |
|
|
integrated with a Python WSGI application. The following are some of its |
|
|
features: |
|
|
features: |
|
|
|
|
|
|
|
@ -49,6 +49,10 @@ written in JavaScript. |
|
|
Getting Started |
|
|
Getting Started |
|
|
--------------- |
|
|
--------------- |
|
|
|
|
|
|
|
|
|
|
|
The Socket.IO server can be installed with pip:: |
|
|
|
|
|
|
|
|
|
|
|
pip install python-socketio |
|
|
|
|
|
|
|
|
The following is a basic example of a Socket.IO server that uses Flask to |
|
|
The following is a basic example of a Socket.IO server that uses Flask to |
|
|
deploy the client code to the browser:: |
|
|
deploy the client code to the browser:: |
|
|
|
|
|
|
|
@ -106,8 +110,8 @@ Rooms |
|
|
|
|
|
|
|
|
Because Socket.IO is a bidirectional protocol, the server can send messages to |
|
|
Because Socket.IO is a bidirectional protocol, the server can send messages to |
|
|
any connected client at any time. To make it easy to address groups of clients, |
|
|
any connected client at any time. To make it easy to address groups of clients, |
|
|
the application can put clients into rooms, and then address messages to all |
|
|
the application can put clients into rooms, and then address messages to the |
|
|
the clients in a room. |
|
|
entire room. |
|
|
|
|
|
|
|
|
When clients first connect, they are assigned to their own rooms, named with |
|
|
When clients first connect, they are assigned to their own rooms, named with |
|
|
the session ID (the ``sid`` argument passed to all event handlers). The |
|
|
the session ID (the ``sid`` argument passed to all event handlers). The |
|
@ -204,6 +208,65 @@ methods in the :class:`socketio.Server` class. |
|
|
When the ``namespace`` argument is omitted, set to ``None`` or to ``'/'``, the |
|
|
When the ``namespace`` argument is omitted, set to ``None`` or to ``'/'``, the |
|
|
default namespace, representing the physical connection, is used. |
|
|
default namespace, representing the physical connection, is used. |
|
|
|
|
|
|
|
|
|
|
|
Using a Message Queue |
|
|
|
|
|
--------------------- |
|
|
|
|
|
|
|
|
|
|
|
The Socket.IO server owns the socket connections to all the clients, so it is |
|
|
|
|
|
the only process that can emit events to them. A common need of larger |
|
|
|
|
|
applications is to emit events to clients from a different process, like a |
|
|
|
|
|
a `Celery <http://www.celeryproject.org/>`_ worker, or any other auxiliary |
|
|
|
|
|
process that works in conjunction with the server. |
|
|
|
|
|
|
|
|
|
|
|
To enable these other processes to emit events, the server can be configured |
|
|
|
|
|
to listen for events to emit to clients on a message queue such as |
|
|
|
|
|
`Redis <http://redis.io/>`_ or `RabbitMQ <https://www.rabbitmq.com/>`_. |
|
|
|
|
|
Processes that need to emit events to client then post these events to the |
|
|
|
|
|
queue. |
|
|
|
|
|
|
|
|
|
|
|
Another situation in which the use of a message queue is necessary is with |
|
|
|
|
|
high traffic applications that work with large number of clients. To support |
|
|
|
|
|
these clients, it may be necessary to horizontally scale the Socket.IO |
|
|
|
|
|
server by splitting the client list among multiple server processes. For this |
|
|
|
|
|
type of installation, the server processes communicate with each other through |
|
|
|
|
|
ta message queue. |
|
|
|
|
|
|
|
|
|
|
|
The message queue service needs to be installed and configured separately. By |
|
|
|
|
|
default, the server uses `Kombu <http://kombu.readthedocs.org/en/latest/>`_ |
|
|
|
|
|
to read and write to the queue, so any message queue supported by this package |
|
|
|
|
|
can be used. Kombu can be installed with pip:: |
|
|
|
|
|
|
|
|
|
|
|
pip install kombu |
|
|
|
|
|
|
|
|
|
|
|
To configure a Socket.IO server to connect to a message queue, the |
|
|
|
|
|
``client_manager`` argument must be passed in the server creation. The |
|
|
|
|
|
following example instructs the server to connect to a Redis service running |
|
|
|
|
|
on the same host and on the default port:: |
|
|
|
|
|
|
|
|
|
|
|
redis = socketio.KombuManager('redis://localhost:6379/') |
|
|
|
|
|
sio = socketio.Server(client_manager=redis) |
|
|
|
|
|
|
|
|
|
|
|
For a RabbitMQ queue also running on the local server, the configuration is |
|
|
|
|
|
as follows:: |
|
|
|
|
|
|
|
|
|
|
|
amqp = socketio.KombuManager('amqp://guest:guest@localhost:5672//') |
|
|
|
|
|
sio = socketio.Server(client_manager=amqp) |
|
|
|
|
|
|
|
|
|
|
|
The arguments passed to the ``KombuManager`` constructor are passed directly |
|
|
|
|
|
to Kombu's `Connection object |
|
|
|
|
|
<http://kombu.readthedocs.org/en/latest/userguide/connections.html>`_. |
|
|
|
|
|
|
|
|
|
|
|
If multiple Sokcet.IO servers are connected to a message queue, they |
|
|
|
|
|
automatically communicate with each other and manage a combine client list, |
|
|
|
|
|
without any need for additional configuration. To have a process other than |
|
|
|
|
|
the server connect to the queue to emit a message, the same ``KombuManager`` |
|
|
|
|
|
class can be used. For example:: |
|
|
|
|
|
|
|
|
|
|
|
# connect to the redis queue |
|
|
|
|
|
redis = socketio.KombuManager('redis://localhost:6379/') |
|
|
|
|
|
|
|
|
|
|
|
# emit an event |
|
|
|
|
|
redis.emit('my event', data={'foo': 'bar'}, room='my room') |
|
|
|
|
|
|
|
|
Deployment |
|
|
Deployment |
|
|
---------- |
|
|
---------- |
|
|
|
|
|
|
|
@ -239,16 +302,14 @@ command to launch the application under gunicorn is shown below:: |
|
|
$ gunicorn -k eventlet -w 1 module:app |
|
|
$ gunicorn -k eventlet -w 1 module:app |
|
|
|
|
|
|
|
|
Due to limitations in its load balancing algorithm, gunicorn can only be used |
|
|
Due to limitations in its load balancing algorithm, gunicorn can only be used |
|
|
with one worker process, so the ``-w 1`` option is required. Note that a |
|
|
with one worker process, so the ``-w`` option cannot be set to a value higher |
|
|
single eventlet worker can handle a large number of concurrent clients. |
|
|
than 1. A single eventlet worker can handle a large number of concurrent |
|
|
|
|
|
clients, each handled by a greenlet. |
|
|
Another limitation when using gunicorn is that the WebSocket transport is not |
|
|
|
|
|
available, because this transport it requires extensions to the WSGI standard. |
|
|
|
|
|
|
|
|
|
|
|
Note: Eventlet provides a ``monkey_patch()`` function that replaces all the |
|
|
Eventlet provides a ``monkey_patch()`` function that replaces all the blocking |
|
|
blocking functions in the standard library with equivalent asynchronous |
|
|
functions in the standard library with equivalent asynchronous versions. While |
|
|
versions. While python-socketio does not require monkey patching, other |
|
|
python-socketio does not require monkey patching, other libraries such as |
|
|
libraries such as database drivers are likely to require it. |
|
|
database drivers are likely to require it. |
|
|
|
|
|
|
|
|
Gevent |
|
|
Gevent |
|
|
~~~~~~ |
|
|
~~~~~~ |
|
@ -293,14 +354,14 @@ Or to include WebSocket:: |
|
|
$ gunicorn -k geventwebsocket.gunicorn.workers.GeventWebSocketWorker -w 1 module: app |
|
|
$ gunicorn -k geventwebsocket.gunicorn.workers.GeventWebSocketWorker -w 1 module: app |
|
|
|
|
|
|
|
|
Same as with eventlet, due to limitations in its load balancing algorithm, |
|
|
Same as with eventlet, due to limitations in its load balancing algorithm, |
|
|
gunicorn can only be used with one worker process, so the ``-w 1`` option is |
|
|
gunicorn can only be used with one worker process, so the ``-w`` option cannot |
|
|
required. Note that a single eventlet worker can handle a large number of |
|
|
be higher than 1. A single gevent worker can handle a large number of |
|
|
concurrent clients. |
|
|
concurrent clients through the use of greenlets. |
|
|
|
|
|
|
|
|
Note: Gevent provides a ``monkey_patch()`` function that replaces all the |
|
|
Gevent provides a ``monkey_patch()`` function that replaces all the blocking |
|
|
blocking functions in the standard library with equivalent asynchronous |
|
|
functions in the standard library with equivalent asynchronous versions. While |
|
|
versions. While python-socketio does not require monkey patching, other |
|
|
python-socketio does not require monkey patching, other libraries such as |
|
|
libraries such as database drivers are likely to require it. |
|
|
database drivers are likely to require it. |
|
|
|
|
|
|
|
|
Standard Threading Library |
|
|
Standard Threading Library |
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
@ -351,14 +412,11 @@ multiple servers), the following conditions must be met: |
|
|
using eventlet, gevent, or standard threads. Worker processes that only |
|
|
using eventlet, gevent, or standard threads. Worker processes that only |
|
|
handle one request at a time are not supported. |
|
|
handle one request at a time are not supported. |
|
|
- The load balancer must be configured to always forward requests from a |
|
|
- The load balancer must be configured to always forward requests from a |
|
|
client to the same process. Load balancers call this *sticky sessions*, or |
|
|
client to the same worker process. Load balancers call this *sticky |
|
|
*session affinity*. |
|
|
sessions*, or *session affinity*. |
|
|
|
|
|
- The worker processes communicate with each other through a message queue, |
|
|
A limitation in the current release of the Socket.IO server is that because |
|
|
which must be installed and configured. See the section on using message |
|
|
the clients are randomly assigned to different server processes, any form of |
|
|
queues above for instructions. |
|
|
broadcasting is not supported. A storage backend that enables multiple |
|
|
|
|
|
processes to share information about clients is currently in development to |
|
|
|
|
|
address this important limitation. |
|
|
|
|
|
|
|
|
|
|
|
API Reference |
|
|
API Reference |
|
|
------------- |
|
|
------------- |
|
|