@@ -49,27 +49,85 @@ ASGI application::
4949 # wrap with ASGI application
5050 app = socketio.ASGIApp(sio)
5151
52- The WSGI and ASGI application wrappers support serving static files, which is
53- a convenient way to deliver JavaScript based Socket.IO clients to the web
54- browser ::
52+ These two wrappers can also act as middlewares, forwarding any traffic that is
53+ not intended to the Socket.IO server to another application. This allows
54+ Socket.IO servers to integrate easily into existing WSGI or ASGI applications ::
5555
56- app = socketio.ASGIApp(sio, static_files={
57- '/': {'content_type': 'text/html', 'filename': 'latency.html'},
58- '/static/style.css': {'content_type': 'text/css',
59- 'filename': 'static/style.css'},
60- })
56+ from wsgi import app # a Flask, Django, etc. application
57+ app = socketio.WSGIApp(sio, app)
6158
62- The dictionary provided with the ``static_files `` argument has static file
63- endpoints as keys. For each of these endpoints, a dictionary with the file's
64- content type and local filename is given.
59+ Serving Static Files
60+ --------------------
6561
66- These wrappers can also act as middlewares, forwarding any traffic that is not
67- intended to Socket.IO server to another application. This allows Socket.IO
68- servers to integrate easily into existing WSGI or ASGI applications::
62+ This package offers the option to configure the serving of static files. This
63+ is particularly useful to deliver HTML, CSS and JavaScript files to clients
64+ when this package is used without a companion web framework.
6965
70- from wsgi import app # a Flask, Django, etc. application
66+ Static files are configured with a Python dictionary in which each key/value
67+ pair is a static file mapping rule. In its simplest form, this dictionary has
68+ one or more static file URLs as keys, and the corresponding files in the server
69+ as values::
7170
72- app = socketio.WSGIApp(sio, app)
71+ static_files = {
72+ '/': 'latency.html',
73+ '/static/socket.io.js': 'static/socket.io.js',
74+ '/static/style.css': 'static/style.css',
75+ }
76+
77+ With this example configuration, when the server receives a request for ``/ ``
78+ (the root URL) it will return the contents of the file ``latency.html `` in the
79+ current directory, and will assign a content type based on the file extension,
80+ in this case ``text/html ``.
81+
82+ Files with the ``.html ``, ``.css ``, ``.js ``, ``.json ``, ``.jpg ``, ``.png ``,
83+ ``.gif `` and ``.txt `` file extensions are automatically recognized and
84+ assigned the correct content type. For files with other file extensions or
85+ with no file extension, the ``application/octet-stream `` content type is used
86+ as a default.
87+
88+ If desired, an explicit content type for a static file can be given as follows::
89+
90+ static_files = {
91+ '/': {'filename': 'latency.html', 'content_type': 'text/plain'},
92+ }
93+
94+ Finally, it is also possible to configure an entire directory in a single rule,
95+ so that all the files in it are served as static files::
96+
97+ static_files = {
98+ '/static': './public',
99+ '/': './public/index.html',
100+ }
101+
102+ In this example any files with URLs starting with ``/static `` will be served
103+ directly from the ``public `` folder in the current directory, so for example,
104+ the URL ``/static/index.html `` will return local file ``./public/index.html ``
105+ and the URL ``/static/css/styles.css `` will return local file
106+ ``./public/css/styles.css ``. The second rule creates a default mapping for the
107+ ``index.html `` file when the root URL is requested.
108+
109+ The static file configuration dictionary is given as the ``static_files ``
110+ argument to the ``socketio.WSGIApp `` or ``socketio.ASGIApp `` classes::
111+
112+ # for standard WSGI applications
113+ sio = socketio.Server()
114+ app = socketio.WSGIApp(sio, static_files=static_files)
115+
116+ # for asyncio-based ASGI applications
117+ sio = socketio.AsyncServer()
118+ app = socketio.ASGIApp(sio, static_files=static_files)
119+
120+ The routing precedence in these two classes is as follows:
121+
122+ - First, the path is checked against the Socket.IO endpoint.
123+ - Next, the path is checked against the static file configuration, if present.
124+ - If the path did not match the Socket.IO endpoint or any static file, control
125+ is passed to the secondary application if configured, else a 404 error is
126+ returned.
127+
128+ Note: static file serving is intended for development use only, and as such
129+ it lacks important features such as caching. Do not use in a production
130+ environment.
73131
74132Defining Event Handlers
75133-----------------------
@@ -490,7 +548,7 @@ explicitly, the ``async_mode`` option can be given in the constructor::
490548 sio = socketio.AsyncServer(async_mode='tornado')
491549
492550A server configured for tornado must include a request handler for
493- Engine .IO::
551+ Socket .IO::
494552
495553 app = tornado.web.Application(
496554 [
@@ -572,10 +630,10 @@ explicitly, the ``async_mode`` option can be given in the constructor::
572630
573631 sio = socketio.Server(async_mode='eventlet')
574632
575- A server configured for eventlet is deployed as a regular WSGI application,
576- using the provided ``socketio.Middleware ``::
633+ A server configured for eventlet is deployed as a regular WSGI application
634+ using the provided ``socketio.WSGIApp ``::
577635
578- app = socketio.Middleware (sio)
636+ app = socketio.WSGIApp (sio)
579637 import eventlet
580638 eventlet.wsgi.server(eventlet.listen(('', 8000)), app)
581639
@@ -614,10 +672,10 @@ option can be given in the constructor::
614672
615673 sio = socketio.Server(async_mode='gevent')
616674
617- A server configured for gevent is deployed as a regular WSGI application,
618- using the provided ``socketio.Middleware ``::
675+ A server configured for gevent is deployed as a regular WSGI application
676+ using the provided ``socketio.WSGIApp ``::
619677
620- app = socketio.Middleware (sio)
678+ app = socketio.WSGIApp (sio)
621679 from gevent import pywsgi
622680 pywsgi.WSGIServer(('', 8000), app).serve_forever()
623681
@@ -626,7 +684,7 @@ follows::
626684
627685 from gevent import pywsgi
628686 from geventwebsocket.handler import WebSocketHandler
629- app = socketio.Middleware (sio)
687+ app = socketio.WSGIApp (sio)
630688 pywsgi.WSGIServer(('', 8000), app,
631689 handler_class=WebSocketHandler).serve_forever()
632690
@@ -699,7 +757,7 @@ development web server based on Werkzeug::
699757
700758 sio = socketio.Server(async_mode='threading')
701759 app = Flask(__name__)
702- app.wsgi_app = socketio.Middleware (sio, app.wsgi_app)
760+ app.wsgi_app = socketio.WSGIApp (sio, app.wsgi_app)
703761
704762 # ... Socket.IO and Flask handler functions ...
705763
0 commit comments