From 5529fbb2bd13654ed34094629bf77250ccf60167 Mon Sep 17 00:00:00 2001
From: Miguel Grinberg <miguelgrinberg50@gmail.com>
Date: Sun, 28 Aug 2016 09:28:11 -0700
Subject: [PATCH] document the use of the new gevent_uwsgi async mode

---
 docs/index.rst      | 23 +++++++++++++++++++++++
 examples/app.py     |  9 +++++++--
 examples/latency.py | 14 +++++++++-----
 socketio/server.py  | 13 ++++++++-----
 4 files changed, 47 insertions(+), 12 deletions(-)

diff --git a/docs/index.rst b/docs/index.rst
index 93a1eab..f72b15f 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -428,6 +428,29 @@ 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 with uWSGI
+~~~~~~~~~~~~~~~~~
+
+When using the uWSGI server in combination with gevent, the Socket.IO server
+can take advantage of uWSGI's native WebSocket support.
+
+Instances of class ``socketio.Server`` will automatically use this option for
+asynchronous operations if both gevent and uWSGI are installed and eventlet is
+not installed. To request this asynchoronous mode explicitly, the
+``async_mode`` option can be given in the constructor::
+
+    # gevent with uWSGI
+    sio = socketio.Server(async_mode='gevent_uwsgi')
+
+A complete explanation of the configuration and usage of the uWSGI server is
+beyond the scope of this documentation. The uWSGI server is a fairly complex
+package that provides a large and comprehensive set of options. It must be
+compiled with WebSocket and SSL support for the WebSocket transport to be
+available. As way of an introduction, the following command starts a uWSGI
+server for the ``latency.py`` example on port 5000::
+
+    $ uwsgi --http :5000 --gevent 1000 --http-websockets --master --wsgi-file latency.py --callable app
+
 Standard Threading Library
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/examples/app.py b/examples/app.py
index 5f3f63e..7f4fe4a 100755
--- a/examples/app.py
+++ b/examples/app.py
@@ -1,5 +1,6 @@
-# set async_mode to 'threading', 'eventlet' or 'gevent' to force a mode
-# else, the best mode is selected automatically from what's installed
+# set async_mode to 'threading', 'eventlet', 'gevent' or 'gevent_uwsgi' to
+# force a mode else, the best mode is selected automatically from what's
+# installed
 async_mode = None
 
 import time
@@ -108,5 +109,9 @@ if __name__ == '__main__':
                               handler_class=WebSocketHandler).serve_forever()
         else:
             pywsgi.WSGIServer(('', 5000), app).serve_forever()
+    elif sio.async_mode == 'gevent_uwsgi':
+        print('Start the application through the uwsgi server. Example:')
+        print('uwsgi --http :5000 --gevent 1000 --http-websockets --master '
+              '--wsgi-file app.py --callable app')
     else:
         print('Unknown async_mode: ' + sio.async_mode)
diff --git a/examples/latency.py b/examples/latency.py
index e43a2f3..45252f9 100755
--- a/examples/latency.py
+++ b/examples/latency.py
@@ -1,11 +1,11 @@
-from flask import Flask, render_template
+# set async_mode to 'threading', 'eventlet', 'gevent' or 'gevent_uwsgi' to
+# force a mode else, the best mode is selected automatically from what's
+# installed
+async_mode = None
 
+from flask import Flask, render_template
 import socketio
 
-# set async_mode to 'threading', 'eventlet' or 'gevent' to force a mode
-# else, the best mode is selected automatically from what's installed
-async_mode = None
-
 sio = socketio.Server(async_mode=async_mode)
 app = Flask(__name__)
 app.wsgi_app = socketio.Middleware(sio, app.wsgi_app)
@@ -43,5 +43,9 @@ if __name__ == '__main__':
                               handler_class=WebSocketHandler).serve_forever()
         else:
             pywsgi.WSGIServer(('', 5000), app).serve_forever()
+    elif sio.async_mode == 'gevent_uwsgi':
+        print('Start the application through the uwsgi server. Example:')
+        print('uwsgi --http :5000 --gevent 1000 --http-websockets --master '
+              '--wsgi-file latency.py --callable app')
     else:
         print('Unknown async_mode: ' + sio.async_mode)
diff --git a/socketio/server.py b/socketio/server.py
index 0dd3979..952641a 100644
--- a/socketio/server.py
+++ b/socketio/server.py
@@ -37,11 +37,14 @@ class Server(object):
 
     The Engine.IO configuration supports the following settings:
 
-    :param async_mode: The library used for asynchronous operations. Valid
-                       options are "threading", "eventlet" and "gevent". If
-                       this argument is not given, "eventlet" is tried first,
-                       then "gevent", and finally "threading". The websocket
-                       transport is only supported in "eventlet" mode.
+    :param async_mode: The asynchronous model to use. See the Deployment
+                       section in the documentation for a description of the
+                       available options. Valid async modes are "threading",
+                       "eventlet", "gevent" and "gevent_uwsgi". If this
+                       argument is not given, "eventlet" is tried first, then
+                       "gevent_uwsgi", then "gevent", and finally "threading".
+                       The first async mode that has all its dependencies
+                       installed is then one that is chosen.
     :param ping_timeout: The time in seconds that the client waits for the
                          server to respond before disconnecting.
     :param ping_interval: The interval in seconds at which the client pings