diff --git a/docs/index.rst b/docs/index.rst
index 151e690..acb66a2 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -8,7 +8,7 @@ socketio documentation
: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
features:
@@ -49,6 +49,10 @@ written in JavaScript.
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
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
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 clients in a room.
+the application can put clients into rooms, and then address messages to the
+entire room.
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
@@ -204,6 +208,65 @@ methods in the :class:`socketio.Server` class.
When the ``namespace`` argument is omitted, set to ``None`` or to ``'/'``, the
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 `_ 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 `_ or `RabbitMQ `_.
+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 `_
+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
+`_.
+
+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
----------
@@ -239,16 +302,14 @@ command to launch the application under gunicorn is shown below::
$ gunicorn -k eventlet -w 1 module:app
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
-single eventlet worker can handle a large number of concurrent clients.
-
-Another limitation when using gunicorn is that the WebSocket transport is not
-available, because this transport it requires extensions to the WSGI standard.
+with one worker process, so the ``-w`` option cannot be set to a value higher
+than 1. A single eventlet worker can handle a large number of concurrent
+clients, each handled by a greenlet.
-Note: Eventlet provides a ``monkey_patch()`` function that replaces all the
-blocking functions in the standard library with equivalent asynchronous
-versions. While python-socketio does not require monkey patching, other
-libraries such as database drivers are likely to require it.
+Eventlet provides a ``monkey_patch()`` function that replaces all the blocking
+functions in the standard library with equivalent asynchronous versions. While
+python-socketio does not require monkey patching, other libraries such as
+database drivers are likely to require it.
Gevent
~~~~~~
@@ -293,14 +354,14 @@ Or to include WebSocket::
$ gunicorn -k geventwebsocket.gunicorn.workers.GeventWebSocketWorker -w 1 module: app
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
-required. Note that a single eventlet worker can handle a large number of
-concurrent clients.
+gunicorn can only be used with one worker process, so the ``-w`` option cannot
+be higher than 1. A single gevent worker can handle a large number of
+concurrent clients through the use of greenlets.
-Note: Gevent provides a ``monkey_patch()`` function that replaces all the
-blocking functions in the standard library with equivalent asynchronous
-versions. While python-socketio does not require monkey patching, other
-libraries such as database drivers are likely to require it.
+Gevent provides a ``monkey_patch()`` function that replaces all the blocking
+functions in the standard library with equivalent asynchronous versions. While
+python-socketio does not require monkey patching, other libraries such as
+database drivers are likely to require it.
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
handle one request at a time are not supported.
- The load balancer must be configured to always forward requests from a
- client to the same process. Load balancers call this *sticky sessions*, or
- *session affinity*.
-
-A limitation in the current release of the Socket.IO server is that because
-the clients are randomly assigned to different server processes, any form of
-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.
+ client to the same worker process. Load balancers call this *sticky
+ sessions*, or *session affinity*.
+- The worker processes communicate with each other through a message queue,
+ which must be installed and configured. See the section on using message
+ queues above for instructions.
API Reference
-------------