python-socketio文档3--(服务端)

Socket.IO 服务器

此软件包包含两个 Socket.IO 服务器:

socketio.Server() 类可创建与 Python 标准库兼容的服务器。

socketio.AsyncServer() 类可创建与 asyncio 软件包兼容的服务器。

这两个服务器中的方法相同,唯一的区别在于,asyncio 服务器中的大多数方法是以协程形式实现的。

安装

若要安装 Socket.IO 服务器及其依赖项,可使用以下命令:

pip install python-socketio

若你打算基于 asyncio 软件包构建异步 Web 服务器,可使用以下命令安装此软件包及所需的其他依赖项:

pip install "python-socketio[asyncio]"

创建服务器实例

Socket.IO 服务器是 socketio.Server 类的一个实例:

import socketio

# 创建一个 Socket.IO 服务器
sio = socketio.Server()

对于基于 asyncio 的服务器,socketio.AsyncServer 类提供了相同的功能,但采用了更适合协程的格式:

import socketio

# 创建一个 Socket.IO 服务器
sio = socketio.AsyncServer()

运行服务器

要运行 Socket.IO 应用程序,需要配置一个 Web 服务器,以接收来自客户端的传入请求,并将其转发给 Socket.IO 服务器实例。为简化此任务,有多种集成方式可供选择,其中包括对 WSGI 和 ASGI 标准的支持。

扫描二维码关注公众号,回复: 17583147 查看本文章

作为 WSGI 应用程序运行

若要将 Socket.IO 服务器配置为 WSGI 应用程序,可使用 socketio.WSGIApp 类包装服务器实例:

# 用 WSGI 应用程序包装
app = socketio.WSGIApp(sio)

生成的 WSGI 应用程序可使用支持 WSGI 的服务器来执行,例如开发环境中使用的 Werkzeug 和生产环境中使用的 Gunicorn。

当将 Socket.IO 与使用 Flask 或 Django 等 WSGI 框架编写的 Web 应用程序结合使用时,WSGIApp 类可将两个应用程序包装在一起,并将流量路由到它们:

from mywebapp import app  # 一个 Flask、Django 等应用程序
app = socketio.WSGIApp(sio, app)

作为 ASGI 应用程序运行

若要将 Socket.IO 服务器配置为 ASGI 应用程序,可使用 socketio.ASGIApp 类包装服务器实例:

# 用 ASGI 应用程序包装
app = socketio.ASGIApp(sio)

生成的 ASGI 应用程序可使用符合 ASGI 标准的 Web 服务器来执行,例如 Uvicorn。

Socket.IO 还可与使用 FastAPI 等 ASGI Web 框架编写的 Web 应用程序结合使用。在这种情况下,ASGIApp 类可将两个应用程序包装在一起,并将流量路由到它们:

from mywebapp import app  # 一个 FastAPI 或其他 ASGI 应用程序
app = socketio.ASGIApp(sio, app)

提供静态文件

可以将 Socket.IO 服务器配置为向客户端提供静态文件。当此软件包在没有配套 Web 框架的情况下使用时,这对于向客户端交付 HTML、CSS 和 JavaScript 文件特别有用。

静态文件通过一个 Python 字典进行配置,其中每个键值对都是一个静态文件映射规则。最简单的形式是,这个字典以一个或多个静态文件的 URL 作为键,以服务器中对应的文件作为值:

static_files = {
    '/': 'latency.html',
    '/static/socket.io.js': 'static/socket.io.js',
    '/static/style.css': 'static/style.css',
}

通过此示例配置,当服务器收到对 /(根 URL)的请求时,它将返回当前目录中 latency.html 文件的内容,并根据文件扩展名分配内容类型,在这种情况下为 text/html

扩展名为 .html.css.js.json.jpg.png.gif 和 .txt 的文件会被自动识别并分配正确的内容类型。对于其他扩展名或无扩展名的文件,默认使用 application/octet-stream 作为内容类型。

如果需要,可为静态文件指定显式的内容类型,如下所示:

static_files = {
    '/': {'filename': 'latency.html', 'content_type': 'text/plain'},
}

也可以在一个规则中配置整个目录,以便将其中的所有文件作为静态文件提供:

static_files = {
    '/static': './public',
}

在此示例中,任何以 /static 开头的 URL 请求的文件都将直接从当前目录的 public 文件夹中提供。例如,URL /static/index.html 将返回本地文件 ./public/index.html,URL /static/css/styles.css 将返回本地文件 ./public/css/styles.css

如果请求的 URL 以 / 结尾,则会自动在其后追加默认文件名 index.html。在前面的示例中,对 /static/ URL 的请求将返回本地文件 ./public/index.html。对于以斜杠结尾的 URL 要提供的默认文件名,可以在静态文件字典中使用空键进行设置:

static_files = {
    '/static': './public',
    '': 'image.gif',
}

通过此配置,对 /static/ 的请求将返回本地文件 ./public/image.gif。如有需要,也可以指定非标准的内容类型:

static_files = {
    '/static': './public',
    '': {'filename': 'image.gif', 'content_type': 'text/plain'},
}

静态文件配置字典作为 static_files 参数传递给 socketio.WSGIApp 或 socketio.ASGIApp 类:

# 对于标准的 WSGI 应用程序
sio = socketio.Server()
app = socketio.WSGIApp(sio, static_files=static_files)

# 对于基于 asyncio 的 ASGI 应用程序
sio = socketio.AsyncServer()
app = socketio.ASGIApp(sio, static_files=static_files)

这两个类中的路由优先级如下:

  1. 首先,检查路径是否与 Socket.IO 端点匹配。
  2. 接着,若存在静态文件配置,则检查路径是否与之匹配。
  3. 若路径与 Socket.IO 端点或任何静态文件均不匹配,且配置了二级应用程序,则将控制权传递给该应用程序;否则返回 404 错误。

注意:静态文件服务仅用于开发环境,因此缺少缓存等重要功能,请勿在生产环境中使用。

事件

Socket.IO 协议基于事件当客户端想与服务器通信,或者服务器想与一个或多个客户端通信时,它们会向对方发送一个事件。每个事件都有一个名称,还可以有一个可选的参数列表。

监听事件

为了接收来自客户端的事件,服务器应用程序必须注册事件处理函数。当客户端发出相应事件时,这些函数会被调用。要为某个事件注册处理函数,可使用 socketio.Server.event() 或 socketio.Server.on() 装饰器:

@sio.event
def my_event(sid, data):
    pass

@sio.on('my custom event')
def another_event(sid, data):
    pass

在第一个例子中,事件名称是从处理函数的名称获取的。第二个例子稍微详细一些,但它允许事件名称与函数名称不同,或者包含函数名称中不合法的字符,例如空格。

对于使用 asyncio 的服务器,事件处理函数可以选择作为协程提供:

@sio.event
async def my_event(sid, data):
    pass

传递给所有处理函数的 sid 参数是 Socket.IO 会话 ID,这是 Socket.IO 为每个客户端连接分配的唯一标识符。给定客户端发送的所有事件都将具有相同的 sid 值。

连接和断开连接事件

连接(connect)和断开连接(disconnect)事件比较特殊;当客户端连接到服务器或从服务器断开连接时,它们会自动被调用:

@sio.event
def connect(sid, environ, auth):
    print('connect ', sid)

@sio.event
def disconnect(sid, reason):
    print('disconnect ', sid, reason)

连接事件是执行用户身份验证的理想时机,也是在应用程序中的用户实体和分配给客户端的 sid 之间进行必要映射的好地方。

除了 sid 之外,连接处理函数还会接收 environ 作为参数,其中包含标准 WSGI 格式的请求信息,包括 HTTP 标头。连接处理函数还会接收 auth 参数,其中包含客户端传递的任何身份验证详细信息;如果客户端未传递任何身份验证信息,则为 None

在检查参数之后,连接事件处理函数可以返回 False 以拒绝与客户端的连接。有时&#