Skip to content

Commit

Permalink
fixed unit tests, improved documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
miguelgrinberg committed Aug 9, 2015
1 parent 5a350c7 commit 5d395a8
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 26 deletions.
4 changes: 3 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
language: python
python:
- "2.7"
- "2.6"
- "3.3"
- "3.4"
- "pypy"
install: python setup.py install
script: python setup.py test
68 changes: 58 additions & 10 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,56 @@ connection to the server. Versions 1.3.5 or newer of the Socket.IO client are
recommended. Versions of the Socket.IO client prior to 1.0 are not supported
anymore.

Note that older versions of Flask-SocketIO had a completely different set of
requirements. These versions had a dependency on
`gevent-socketio <https://gevent-socketio.readthedocs.org/en/latest/>`_ and
`gevent-websocket <https://bitbucket.org/Jeffrey/gevent-websocket>`_, which are
not used anymore.

Current Limitations
~~~~~~~~~~~~~~~~~~~

- Flask-SocketIO can only run in a single worker process at this time. Work is
currently in progress to eliminate this limitation.

Differences With Flask-SocketIO Versions 0.x
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Older versions of Flask-SocketIO had a completely different set of
requirements. These versions had a dependency on
`gevent-socketio <https://gevent-socketio.readthedocs.org/en/latest/>`_ and
`gevent-websocket <https://bitbucket.org/Jeffrey/gevent-websocket>`_, which
were dropped in release 1.0.

In spite of the change in dependencies, there aren't many significant
changes introduced in version 1.0. Below is a detailed list of
the actual differences:

- Release 1.0 drops support for Python 2.6, and adds support for Python 3.3,
Python 3.4, and pypy.
- Releases 0.x required an old version of the Socket.IO Javascript client.
Starting with release 1.0, the current releases of Socket.IO and Engine.IO
are supported.
- The 0.x releases depended on gevent, gevent-socketio and gevent-websocket.
In release 1.0 gevent-socketio and gevent-websocket are not used anymore,
and gevent is one of three options for backend web server, with eventlet
and any regular multi-threaded WSGI server, including Flask's development
web server.
- The Socket.IO server options have changed in release 1.0. They can be
provided in the SocketIO constructor, or in the ``run()`` call. The options
provided in these two are merged before they are used.
- The 0.x releases exposed the gevent-socketio connection as
``request.namespace``. In release 1.0 this is not available anymore. The
request object defines ``request.namespace`` as the name of the namespace
being handled, and adds ``request.sid``, defined as the unique session ID
for the client connection, and ``request.event``, which contains the event
name and arguments.
- To get the list of rooms a client was in the 0.x release required the
application to use a private structure of gevent-socketio, with the
expression ``request.namespace.rooms``. This is not available in release
1.0, which includes a proper ``rooms()`` function.
- The recommended "trick" to send a message to an individual client was to
put each client in a separate room, then address messages to the desired
room. This was formalized in release 1.0, where clients are assigned a room
automatically when they connect.
- The ``'connect'`` event for the global namespace did not fire on releases
prior to 1.0. This has been fixed and now this event fires as expected.
- Support for client-side callbacks was introduced in release 1.0.

Initialization
--------------

Expand Down Expand Up @@ -168,10 +206,20 @@ received by the client::
emit('my response', json, callback=ack)

When using callbacks the Javascript client receives a callback function to
invoke upon receipt of the message. When the client calls the callback
function the server invokes the corresponding server-side callback. The client
can pass arguments in the callback function, which are transferred to the
server and given to the server-side callback as function arguments.
invoke upon receipt of the message. After the client application invokes the
callback function the server invokes the corresponding server-side callback.
If the client-side callback returns any values, these are provided as
arguments to the server-side callback.

The client application can also request an acknoledgement callback for an
event sent to the server. If the server wants to provide arguments for this
callback, it must return them from the event handler function::

@socketio.on('my event')
def handle_my_custom_event(json):
# ... handle the event

return 'foo', 'bar', 123 # client callback will receive these 3 arguments

Broadcasting
------------
Expand Down
32 changes: 18 additions & 14 deletions flask_socketio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def init_app(self, app, **kwargs):
raise RuntimeError('Cannot associate a SocketIO instance with '
'more than one application')
if not hasattr(app, 'extensions'):
app.extensions = {}
app.extensions = {} # pragma: no cover
app.extensions['socketio'] = self
self.server_options = kwargs
self.app = app
Expand Down Expand Up @@ -232,6 +232,7 @@ def run(self, app=None, host=None, port=None, **kwargs):
self.app = app

self.server_options.update(kwargs)
test_mode = self.server_options.pop('test_mode', False)
log_output = self.server_options.pop('log_output', app.debug)
use_reloader = self.server_options.pop('use_reloader', app.debug)
resource = self.server_options.pop('resource', 'socket.io')
Expand All @@ -248,22 +249,25 @@ def run(self, app=None, host=None, port=None, **kwargs):
app.wsgi_app = socketio.Middleware(self.server, app.wsgi_app,
socketio_path=resource)

if self.server.eio.async_mode == 'threading':
app.run(host=host, port=port, threaded=True,
use_reloader=use_reloader)
elif self.server.eio.async_mode == 'eventlet':
import eventlet
eventlet.wsgi.server(eventlet.listen((host, port)), app,
log_output=log_output, **kwargs)
elif self.server.eio.async_mode == 'gevent':
from gevent import pywsgi
log = 'default'
if not log_output:
log = None
pywsgi.WSGIServer((host, port), app, log=log).serve_forever()
if not test_mode:
if self.server.eio.async_mode == 'threading':
app.run(host=host, port=port, threaded=True,
use_reloader=use_reloader)
elif self.server.eio.async_mode == 'eventlet':
import eventlet
eventlet.wsgi.server(eventlet.listen((host, port)), app,
log_output=log_output, **kwargs)
elif self.server.eio.async_mode == 'gevent':
from gevent import pywsgi
log = 'default'
if not log_output:
log = None
pywsgi.WSGIServer((host, port), app, log=log).serve_forever()

def test_client(self, app, namespace=None):
"""Return a simple SocketIO client that can be used for unit tests."""
if self.server is None:
self.run(app, test_mode=True)
return SocketIOTestClient(app, self, namespace)

def _copy_session(self, src, dest):
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

setup(
name='Flask-SocketIO',
version='0.9.0',
version='1.0a1',
url='http://github.com/miguelgrinberg/Flask-SocketIO/',
license='MIT',
author='Miguel Grinberg',
Expand Down

0 comments on commit 5d395a8

Please sign in to comment.