diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index af896fb4..ddc190c8 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -26,7 +26,7 @@ jobs:
exclude:
# pypy3 currently fails to run on Windows
- os: windows-latest
- python: pypy-3.8
+ python: pypy-3.9
fail-fast: false
runs-on: ${{ matrix.os }}
steps:
diff --git a/docs/server.rst b/docs/server.rst
index 5a6798c2..5ce59f00 100644
--- a/docs/server.rst
+++ b/docs/server.rst
@@ -617,6 +617,41 @@ callbacks when emitting. When the external process needs to receive callbacks,
using a client to connect to the server with read and write support is a better
option than a write-only client manager.
+Monitoring and Administration
+-----------------------------
+
+The Socket.IO server can be configured to accept connections from the official
+`Socket.IO Admin UI `_. This tool provides
+real-time information about currently connected clients, rooms in use and
+events being emitted. It also allows an administrator to manually emit events,
+change room assignments and disconnect clients. The hosted version of this tool
+is available at `https://admin.socket.io `_.
+
+Given that enabling this feature can affect the performance of the server, it
+is disabled by default. To enable it, call the
+:func:`instrument() ` method. For example::
+
+ import os
+ import socketio
+
+ sio = socketio.Server(cors_allowed_origins=[
+ 'http://localhost:5000',
+ 'https://admin.socket.io',
+ ])
+ sio.instrument(auth={
+ 'username': 'admin',
+ 'password': os.environ['ADMIN_PASSWORD'],
+ })
+
+This configures the server to accept connections from the hosted Admin UI
+client. Administrators can then open https://admin.socket.io in their web
+browsers and log in with username ``admin`` and the password given by the
+``ADMIN_PASSWORD`` environment variable. To ensure the Admin UI front end is
+allowed to connect, CORS is also configured.
+
+Consult the reference documentation to learn about additional configuration
+options that are available.
+
Debugging and Troubleshooting
-----------------------------
diff --git a/examples/server/asgi/app.py b/examples/server/asgi/app.py
index 22180bb0..36af85f2 100644
--- a/examples/server/asgi/app.py
+++ b/examples/server/asgi/app.py
@@ -1,9 +1,25 @@
#!/usr/bin/env python
-import uvicorn
+# set instrument to `True` to accept connections from the official Socket.IO
+# Admin UI hosted at https://admin.socket.io
+instrument = False
+admin_login = {
+ 'username': 'admin',
+ 'password': 'python', # change this to a strong secret for production use!
+}
+
+import uvicorn
import socketio
-sio = socketio.AsyncServer(async_mode='asgi')
+sio = socketio.AsyncServer(
+ async_mode='asgi',
+ cors_allowed_origins=None if not instrument else [
+ 'http://localhost:5000',
+ 'https://admin.socket.io', # edit the allowed origins if necessary
+ ])
+if instrument:
+ sio.instrument(auth=admin_login)
+
app = socketio.ASGIApp(sio, static_files={
'/': 'app.html',
})
diff --git a/examples/server/wsgi/app.py b/examples/server/wsgi/app.py
index 3339826a..7b019fd0 100644
--- a/examples/server/wsgi/app.py
+++ b/examples/server/wsgi/app.py
@@ -3,10 +3,26 @@
# installed
async_mode = None
+# set instrument to `True` to accept connections from the official Socket.IO
+# Admin UI hosted at https://admin.socket.io
+instrument = False
+admin_login = {
+ 'username': 'admin',
+ 'password': 'python', # change this to a strong secret for production use!
+}
+
from flask import Flask, render_template
import socketio
-sio = socketio.Server(logger=True, async_mode=async_mode)
+sio = socketio.Server(
+ async_mode=async_mode,
+ cors_allowed_origins=None if not instrument else [
+ 'http://localhost:5000',
+ 'https://admin.socket.io', # edit the allowed origins if necessary
+ ])
+if instrument:
+ sio.instrument(auth=admin_login)
+
app = Flask(__name__)
app.wsgi_app = socketio.WSGIApp(sio, app.wsgi_app)
app.config['SECRET_KEY'] = 'secret!'
diff --git a/examples/server/wsgi/templates/index.html b/examples/server/wsgi/templates/index.html
index 7c9ae41f..bec1a628 100644
--- a/examples/server/wsgi/templates/index.html
+++ b/examples/server/wsgi/templates/index.html
@@ -6,7 +6,7 @@