入门指南
socketio是什么?
socketio是一种传输协议,它支持客户机(通常,但不总是web浏览器)和服务器之间基于事件的实时双向通信。
客户端和服务器组件的官方实现是用JavaScript编写的。这个包提供了这两种方法的Python实现,每种方法都有标准版本和asyncio变体版。
客户端案例
下面的例子展示了一个简单的Python客户端:
import socketio
sio = socketio.Client()
@sio.event
def connect():
print('connection established')
@sio.event
def my_message(data):
print('message received with ', data)
sio.emit('my response', {'response': 'my response'})
@sio.event
def disconnect():
print('disconnected from server')
sio.connect('http://localhost:5000')
sio.wait()
下面是一个类似的客户端,为asyncio(仅限Python 3.5+)编码:
import asyncio
import socketio
sio = socketio.AsyncClient()
@sio.event
async def connect():
print('connection established')
@sio.event
async def my_message(data):
print('message received with ', data)
await sio.emit('my response', {'response': 'my response'})
@sio.event
async def disconnect():
print('disconnected from server')
async def main():
await sio.connect('http://localhost:5000')
await sio.wait()
if __name__ == '__main__':
asyncio.run(main())
客户端功能
- 可以连接到其他socket。兼容JavaScript Socket的IO服务器。
- 兼容Python 3.5+。
- 客户端的两个版本,一个用于标准Python,另一个用于asyncio。
- 使用基于事件的体系结构,使用隐藏协议细节的装饰器实现。
- 实现HTTP长轮询和WebSocket传输。
- 如果连接被删除,自动重新连接到服务器。
服务端案例
下面的应用程序是一个使用Eventlet异步服务器的基本服务器示例:
import eventlet
import socketio
sio = socketio.Server()
app = socketio.WSGIApp(sio, static_files={
'/': {'content_type': 'text/html', 'filename': 'index.html'}
})
@sio.event
def connect(sid, environ):
print('connect ', sid)
@sio.event
def my_message(sid, data):
print('message ', data)
@sio.event
def disconnect(sid):
print('disconnect ', sid)
if __name__ == '__main__':
eventlet.wsgi.server(eventlet.listen(('', 5000)), app)
下面是一个类似的应用程序,为asyncio(仅适用于Python 3.5+)和Uvicorn web服务器编写:
import socketio
sio = socketio.AsyncServer()
app = web.Application()
sio.attach(app)
async def index(request):
"""Serve the client-side application."""
with open('index.html') as f:
return web.Response(text=f.read(), content_type='text/html')
@sio.event
def connect(sid, environ):
print("connect ", sid)
@sio.event
async def chat_message(sid, data):
print("message ", data)
@sio.event
def disconnect(sid):
print('disconnect ', sid)
app.router.add_static('/static', 'static')
app.router.add_get('/', index)
if __name__ == '__main__':
web.run_app(app)
服务器功能
- 可以连接到运行其他套接字的服务器。与JavaScript客户端版本兼容的IO客户端倍和2.倍。
- 兼容Python 3.5+。
- 服务器的两个版本,一个用于标准Python,另一个用于asyncio。
- 由于是异步的,即使在普通的硬件上也支持大量的客户机。
- 可以托管在任何WSGI和ASGI web服务器上,包括Gunicorn, Uvicorn, eventlet和gevent。
- 可以与用Flask、Django等框架编写的WSGI应用程序集成。
- 可与aiohttp、sanic和tornado asyncio应用集成。
- 将消息广播给所有连接的客户端,或分配给“房间”的客户端子集。
- 可选支持多服务器,通过消息队列连接,如Redis或RabbitMQ。
- 从外部进程向客户端发送消息,例如Celery 进程或auxiliary 。
- 基于事件的体系结构使用隐藏协议细节的装饰器实现。
- 支持HTTP长轮询和WebSocket传输。
- 支持XHR2和XHR浏览器。
- 支持文本和二进制消息。
- 支持gzip和deflate HTTP压缩。
- 可配置的CORS响应,以避免浏览器的跨源问题。
soketio客户端
安装
pip install "python-socketio"
pip install "python-socketio[client]"
pip install "python-socketio[asyncio_client]"
创建客户端对象
import socketio
# standard Python
sio = socketio.Client()
# asyncio
sio = socketio.AsyncClient()
创建处理器
socketio协议是基于事件的。
当服务器想要与客户端通信时,它会发出一个事件。每个事件都有一个名称和一个参数列表。客户端用socketio.Client.event()或socketio.Client.on()装饰器注册事件处理函数
import socketio
# asyncio
sio = socketio.AsyncClient()
@sio.event
def message(data):
print('我收到了消息')
@sio.on('my message')
def on_message(data):
print('我收到了消息')
在第一个示例中,事件名称是从处理程序函数的名称中获取的。第二个示例稍微详细一些,但它允许事件名与函数名不同,或者允许在函数名中包含非法的字符,如空格。
对于asyncio客户端,事件处理程序可以是上述的常规函数,也可以是协程:
@sio.event
async def message(data):
print('I received a message!')
connect、connect_error和disconnect事件是特殊的;当客户端连接或断开与服务器的连接时,它们会被自动调用:
@sio.event
def connect():
print("I'm connected!")
@sio.event
def connect_error():
print("The connection failed!")
@sio.event
def disconnect():
print("I'm disconnected!")
请注意,当应用程序发起的断开、服务器发起的断开或意外断开(例如由于网络故障)时,会调用断开处理程序。在意外断开连接的情况下,客户端将尝试在调用断开处理程序后立即重新连接。一旦重新建立连接,将再次调用连接处理程序。
如果服务器包含一个事件的参数,这些参数将作为参数传递给处理器函数。
连接服务器
通过调用connect()方法建立到服务器的连接:
sio.connect('http://localhost:5000')
在asyncio客户端中,该方法是协程:
await sio.connect('http://localhost:5000')
在连接时,服务器分配给客户机一个唯一的会话标识符。应用程序可以在sid属性中找到这个标识符:
print('my sid is', sio.sid)
发送事件
客户端可以使用emit()方法向服务器发送事件:
sio.emit('my message', {'foo': 'bar'})
或者在asyncio的情况下,作为协程:
await sio.emit('my message', {'foo': 'bar'})
提供给该方法的唯一参数是传递给服务器的数据。数据类型可以是str、bytes、dict、list或tuple。当发送一个元组时,其中的元素必须是其他四种允许的类型之一。元组的元素将作为多个参数传递给服务器端事件处理函数。
emit()方法可以在事件处理程序中作为对服务器事件的响应调用,也可以在应用程序的任何其他部分(包括后台任务)中调用。
事件回调函数
当服务器向客户端发出事件时,它可以提供回调函数,作为确认服务器已经处理了事件的一种方式调用。虽然这完全由服务器管理,但客户机可以提供返回值列表,这些返回值将被传递给服务器设置的回调函数。这可以通过从handler函数返回所需的值来实现:
@sio.event
def my_event(sid, data):
# handle the message
return "OK", 123
同样,客户端可以请求回调函数,以便在服务器处理事件后调用。socketio.Server.emit()方法有一个可选的回调参数,可以设置为一个可调用对象。如果给出了这个参数,则可调用对象将在服务器处理事件后被调用,服务器处理程序返回的任何值都将作为参数传递给该函数。
名称空间
socketio协议支持多个逻辑连接,在同一个物理连接上复用。客户端可以通过在每个连接上指定不同的名称空间来打开多个连接。名称空间使用以正斜杠开头的路径语法。客户端可以在connect()调用中提供名称空间列表。例如,这个示例创建了两个逻辑连接,默认的一个连接加上/chat命名空间下的第二个连接:
sio.connect('http://localhost:5000', namespaces=['/chat'])
要在命名空间上定义事件处理程序,必须将命名空间参数添加到相应的装饰器中:
@sio.event(namespace='/chat')
def my_custom_event(sid, data):
pass
@sio.on('connect', namespace='/chat')
def on_connect():
print("I'm connected to the /chat namespace!")
同样,客户端可以通过在emit()调用中提供its来在名称空间上向服务器发送事件:
sio.emit('my message', {'foo': 'bar'}, namespace='/chat')
如果没有给出connect()调用的名称空间参数,则事件处理程序中使用的任何名称空间都将自动连接。
类名称空间
作为基于装饰器的事件处理程序的替代方案,属于名称空间的事件处理程序可以作为socketio子类的方法创建。
class MyCustomNamespace(socketio.ClientNamespace):
def on_connect(self):
pass
def on_disconnect(self):
pass
def on_my_event(self, data):
self.emit('my_response', data)
sio.register_namespace(MyCustomNamespace('/chat'))
对于基于asyncio的服务器,名称空间必须继承自socketio.AsyncClientNamespace,如果需要,可以将事件处理程序定义为协程:
class MyCustomNamespace(socketio.AsyncClientNamespace):
def on_connect(self):
pass
def on_disconnect(self):
pass
async def on_my_event(self, data):
await self.emit('my_response', data)
sio.register_namespace(MyCustomNamespace('/chat'))
当使用基于类的名称空间时,客户机接收到的任何事件都被分派到一个以事件名命名并带有on_前缀的方法。例如,事件my_event将由一个名为on_my_event的方法处理。如果接收到的事件在名称空间类中没有定义相应的方法,则该事件将被忽略。在基于类的命名空间中使用的所有事件名称必须使用在方法名称中合法的字符。
为了方便在基于类的命名空间中定义方法,命名空间实例包含了socketio中几个方法的版本。客户端和socketio。当没有给出名称空间参数时,默认使用正确的名称空间的AsyncClient类。
如果事件在基于类的名称空间中有处理程序,同时也有基于装饰器的函数处理程序,则只调用独立的函数处理程序。
断开连接
在任何时候,客户端都可以通过调用disconnect()方法请求断开与服务器的连接:
sio.disconnect()
对于asyncio客户端,这是一个协程:
await sio.disconnect()
管理后台任务
当建立到服务器的客户端连接时,将产生一些后台任务来保持连接并处理传入的事件。运行在主线程上的应用程序可以自由地做任何工作。
如果应用程序在主线程中没有任何事情要做,只是想等待与服务器的连接结束,它可以调用wait()方法:
sio.wait()
或者在asyncio版本中:
await sio.wait()
为了方便应用程序,提供了一个helper函数来启动自定义后台任务:
def my_background_task(my_argument):
# do some background work here!
pass
sio.start_background_task(my_background_task, 123)
传递给该方法的参数是后台函数和任何用于调用函数的位置参数或关键字参数。
下面是asyncio版本:
async def my_background_task(my_argument):
# do some background work here!
pass
sio.start_background_task(my_background_task, 123)
注意,这个函数不是协程,因为它不等待后台函数结束。后台函数必须是协程。
sleep()方法是第二个方便的函数,它是为了应用程序自己处理后台任务而提供的:
sio.sleep(2)
或者在asyncio版本中:
await sio.sleep(2)
调试和故障排除
为了帮助您调试问题,客户端可以配置为输出日志到终端:
import socketio
# standard Python
sio = socketio.Client(logger=True, engineio_logger=True)
# asyncio
sio = socketio.AsyncClient(logger=True, engineio_logger=True)
logger参数控制与套接字相关的日志记录。IO协议,而engineeio_logger控制起源于低级引擎的日志。IO运输。这些参数可以设置为True,以将日志输出到stderr,或输出到与Python日志包兼容的对象,日志应该发送到该对象。False值禁用日志记录。
日志记录可以帮助识别连接问题、意外断开连接和其他问题的原因。
soketio服务器
安装
pip install python-socketio
创建服务器实例
import socketio
# create a Socket.IO server
sio = socketio.Server()
# wrap with a WSGI application
app = socketio.WSGIApp(sio)
对于基于asyncio的服务器,socketio.AsyncServer类提供了相同的功能,但采用协程友好格式。如果需要,插座。ASGIApp类可以将服务器转换为标准的ASGI应用程序:
# create a Socket.IO server
sio = socketio.AsyncServer()
# wrap with ASGI application
app = socketio.ASGIApp(sio)
这两个包装器还可以作为中间件,转发不打算发送到套接字的任何流量。IO服务器到另一个应用程序。这允许插座。将IO服务器集成到现有的WSGI或ASGI应用程序中:
from wsgi import app # a Flask, Django, etc. application
app = socketio.WSGIApp(sio, app)
静态文件
Engine.IO server可以配置为向客户端提供静态文件。当这个包在没有配套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',
}
# for standard WSGI applications
sio = socketio.Server()
app = socketio.WSGIApp(sio, static_files=static_files)
# for asyncio-based ASGI applications
sio = socketio.AsyncServer()
app = socketio.ASGIApp(sio, static_files=static_files)
事件处理器
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参数是套接字。IO会话id,每个客户端连接的唯一标识符。给定客户机发送的所有事件都具有相同的sid值。
连接和断开连接事件是特殊的;当客户端连接或断开与服务器的连接时,它们会被自动调用:
@sio.event
def connect(sid, environ, auth):
print('connect ', sid)
@sio.event
def disconnect(sid):
print('disconnect ', sid)
connect事件是执行用户身份验证以及应用程序中的用户实体与分配给客户机的sid之间的任何必要映射的理想场所。environ参数是一个标准的WSGI格式的字典,包含请求信息,包括HTTP报头。auth参数包含客户端传递的任何身份验证细节,如果客户端没有传递任何信息,则为None。在检查请求之后,connect事件处理程序可以返回False以拒绝与客户机的连接。
有时,将数据传递回被拒绝的客户机是很有用的。在这种情况下,可以引发socketio.exceptions.ConnectionRefusedError,而不是返回False,它的所有参数都将通过拒绝消息发送给客户端:
@sio.event
def connect(sid, environ):
raise ConnectionRefusedError('authentication failed')
提交事件
socketio是一个双向协议,因此在任何时候服务器都可以向其连接的客户端发送事件。socketio.Server.emit()方法用于此任务:
sio.emit('my event', {'data': 'foobar'})
有时,服务器可能只想将事件发送给特定的客户机。这可以通过向emit调用添加room参数来实现:
sio.emit('my event', {'data': 'foobar'}, room=user_sid)
socketio.Server.emit()方法接受一个事件名称、str类型的消息有效负载、字节串、列表、字典或元组以及收件人房间。当发送一个元组时,其中的元素必须是其他四种允许的类型之一。元组的元素将作为多个参数传递给客户端事件处理程序函数。room参数用于标识应该接收事件的客户机,并将其设置为分配给该客户机与服务器的连接的sid值。当省略时,事件将被广播到所有连接的客户端。
事件回调
当客户端向服务器发送事件时,它可以提供回调函数,作为确认服务器已处理事件的一种方式调用。虽然这完全由客户端管理,但服务器可以提供一个值列表,这些值将被传递给回调函数,只需从handler函数返回它们:
@sio.event
def my_event(sid, data):
# handle the message
return "OK", 123
同样,服务器可以请求回调函数,以便在客户端处理事件后调用。socketio.Server.emit()方法有一个可选的回调参数,可以设置为一个可调用对象。如果给出了这个参数,可调用对象将在客户端处理事件后被调用,客户端返回的任何值都将作为参数传递给这个函数。不建议在向多个客户端广播时使用回调函数,因为接收到消息的每个客户端都会调用回调函数一次。
名称空间
soketio协议支持多个逻辑连接,在同一个物理连接上复用。客户端可以通过在每个连接上指定不同的名称空间来打开多个连接。名称空间由客户机作为主机名和端口后面的路径名给出。例如,连接到http://example.com:8000/chat将打开到名称空间/聊天的连接。
每个名称空间都是独立于其他名称空间进行处理的,具有独立的会话id (sid)、事件处理程序和房间。使用多个名称空间的应用程序在设置它们的事件处理程序和房间时必须指定正确的名称空间,这一点很重要,使用socketio中所有方法中可用的可选名称空间参数。服务器类:
@sio.event(namespace='/chat')
def my_custom_event(sid, data):
pass
@sio.on('my custom event', namespace='/chat')
def my_custom_event(sid, data):
pass
在发送事件时,namespace可选参数用于指定发送该事件的名称空间。当namespace参数被省略时,默认套接字。使用的命名空间为“/”。
类名称空间
作为基于装饰器的事件处理程序的替代方案,属于名称空间的事件处理程序可以作为socketio.Namespace:子类的方法创建
class MyCustomNamespace(socketio.Namespace):
def on_connect(self, sid, environ):
pass
def on_disconnect(self, sid):
pass
def on_my_event(self, sid, data):
self.emit('my_response', data)
sio.register_namespace(MyCustomNamespace('/test'))
对于基于asyncio的服务器,名称空间必须继承自socketio.AsyncNamespace,如果需要,可以将事件处理程序定义为协程:
class MyCustomNamespace(socketio.AsyncNamespace):
def on_connect(self, sid, environ):
pass
def on_disconnect(self, sid):
pass
async def on_my_event(self, sid, data):
await self.emit('my_response', data)
sio.register_namespace(MyCustomNamespace('/test'))
当使用基于类的名称空间时,服务器接收到的任何事件都被分派到一个以事件名命名并带有on_前缀的方法。例如,事件my_event将由一个名为on_my_event的方法处理。如果接收到的事件在名称空间类中没有定义相应的方法,则该事件将被忽略。在基于类的命名空间中使用的所有事件名称必须使用在方法名称中合法的字符。
为了方便在基于类的命名空间中定义方法,命名空间实例包含了socketio中几个方法的版本。服务器和socketio。当没有给出命名空间参数时,默认使用正确的命名空间的AsyncServer类。
如果事件在基于类的名称空间中有处理程序,同时也有基于装饰器的函数处理程序,则只调用独立的函数处理程序。
重要的是要注意,基于类的命名空间是单例的。这意味着名称空间类的单个实例用于所有客户机,因此,名称空间实例不能用于存储特定于客户机的信息。
房间
为了方便服务器向相关客户端组发送事件,应用程序可以将其客户端放入“房间”中,然后向这些房间发送消息。
在上一节中,socketio.SocketIO.emit()方法的room参数用于指定一个特定的客户端作为事件的接收者。这是因为在连接时,为每个客户机创建了一个个人房间,并使用分配给连接的sid进行命名。然后应用程序可以自由地创建其他房间,并使用socketio.Server.enter_room()和socketio.Server.leave_room()方法管理其中的哪些客户端。客户可以在需要的尽可能多的房间,并可以经常在房间之间移动。
@sio.event
def begin_chat(sid):
sio.enter_room(sid, 'chat_users')
@sio.event
def exit_chat(sid):
sio.leave_room(sid, 'chat_users')
在聊天应用程序中,通常希望将一个事件广播给房间里的所有成员,除了一个事件的发起者(如聊天消息)。socketio.Server.emit()方法提供了一个可选的skip_sid参数来指示在广播过程中应该跳过的客户端。
@sio.event
def my_message(sid, data):
sio.emit('my reply', data, room='chat_users', skip_sid=sid)
会话
服务器可以在专用于每个连接的客户机的用户会话中维护特定于应用程序的信息。应用程序可以使用用户会话来编写需要在连接的整个生命周期中保存的关于用户的任何细节,例如用户名或用户id。
save_session()和get_session()方法用于存储和检索用户会话中的信息:
@sio.event
def connect(sid, environ):
username = authenticate_user(environ)
sio.save_session(sid, {'username': username})
@sio.event
def message(sid, data):
session = sio.get_session(sid)
print('message from ', session['username'])
对于asyncio服务器,这些方法是协程:
@sio.event
async def connect(sid, environ):
username = authenticate_user(environ)
await sio.save_session(sid, {'username': username})
@sio.event
async def message(sid, data):
session = await sio.get_session(sid)
print('message from ', session['username'])
会话也可以用session()上下文管理器来操作:
@sio.event
def connect(sid, environ):
username = authenticate_user(environ)
with sio.session(sid) as session:
session['username'] = username
@sio.event
def message(sid, data):
with sio.session(sid) as session:
print('message from ', session['username'])
对于asyncio服务器,使用异步上下文管理器:
@sio.event
def connect(sid, environ):
username = authenticate_user(environ)
async with sio.session(sid) as session:
session['username'] = username
@sio.event
def message(sid, data):
async with sio.session(sid) as session:
print('message from ', session['username'])
get_session()、save_session()和session()方法接受一个可选的名称空间参数。如果没有提供此参数,会话将附加到默认名称空间。
注意:当客户端断开连接时,用户会话的内容将被销毁。特别是,当客户端在与服务器意外断开连接后重新连接时,用户会话内容不会被保留。
使用消息队列
在使用分布式应用程序时,通常需要访问套接字的功能。IO来自多个进程。有两个特定的用例:
- 使用工作队列(如celery)的应用程序可能需要在后台作业完成时向客户端发送一个事件。执行这项任务最方便的地方是处理这项工作的工作进程。
- 高可用性应用程序可能希望使用套接字的水平伸缩。socketio服务器能够处理大量并发客户端。
作为解决上述问题的一种方法,Socket.IO server可以配置为连接消息队列,如Redis或RabbitMQ,与其他相关Socket.IO服务器或辅助工作者。
Redis
要使用Redis消息队列,必须安装Python Redis客户端:
# socketio.Server class
pip install redis
# socketio.AsyncServer class
pip install aioredis
Redis队列是通过socket.RedisManager socketio.AsyncRedisManager类配置的。这些类直接连接到Redis store,并使用队列的pub/sub功能:
# socketio.Server class
mgr = socketio.RedisManager('redis://')
sio = socketio.Server(client_manager=mgr)
# socketio.AsyncServer class
mgr = socketio.AsyncRedisManager('redis://')
sio = socketio.AsyncServer(client_manager=mgr)
client_manager参数指示服务器连接到给定的消息队列,并与连接到该队列的其他进程进行协调。
Kombu
Kombu是一个Python包,它提供了对RabbitMQ和许多其他消息队列的访问。可以用pip安装:
pip install kombu
使用RabbitMQ或其他兼容AMQP协议的队列,这是唯一需要的依赖。但对于其他消息队列,Kombu可能需要额外的包。例如,要通过Kombu使用Redis队列,还需要安装Redis的Python包:
pip install redis
队列是通过socketio.KombuManager配置的。
mgr = socketio.KombuManager('amqp://')
sio = socketio.Server(client_manager=mgr)
传递给KombuManager构造函数的连接URL将直接传递给Kombu的连接对象,因此应该参考Kombu文档,了解如何为给定的消息队列构建正确的URL。
注意,Kombu目前不支持asyncio,因此它不能与socketio.AsyncServer类一起使用。
Kafka
Kafka -python包支持Apache Kafka:
pip install kafka-python
对Kafka的访问是通过socket.KafkaManager类配置的。
请注意,Kafka目前不支持asyncio,所以它不能与socketio.AsyncServer类一起使用。
AioPika
在asyncio应用中,通过AioPika包支持RabbitMQ消息队列:
pip install aio_pika
RabbitMQ队列是通过socket.AsyncAioPikaManager类配置的。
mgr = socketio.AsyncAioPikaManager('amqp://')
sio = socketio.AsyncServer(client_manager=mgr)
从外部过程发出
为了让服务器以外的进程连接到队列以发出消息,可以将相同的客户端管理器类用作独立对象。在这种情况下,write_only参数应该设置为True,以禁止创建监听线程,这只在服务器中有意义。例如:
# connect to the redis queue as an external process
external_sio = socketio.RedisManager('redis://', write_only=True)
# emit an event
external_sio.emit('my event', data={'foo': 'bar'}, room='my room')
调试和故障排除
为了帮助您调试问题,可以将服务器配置为输出日志到终端:
import socketio
# standard Python
sio = socketio.Server(logger=True, engineio_logger=True)
# asyncio
sio = socketio.AsyncServer(logger=True, engineio_logger=True)
部署策略
Aiohttp
Aiohttp是一个基于asyncio的框架,支持HTTP和WebSocket。对这个框架的支持仅限于Python 3.5及更新版本。
socketio.AsyncServer类的实例。如果安装了库,将自动使用aiohttp进行异步操作。要请求显式使用async_mode选项,可以在构造函数中给出:
sio = socketio.AsyncServer(async_mode='aiohttp')
为aiohttp配置的服务器必须附加到现有的应用程序:
app = web.Application()
sio.attach(app)
然后以通常的方式执行aiohttp应用程序:
if __name__ == '__main__':
web.run_app(app)
Sanic
Sanic是Python 3.5及更新版本的一个非常高效的异步web服务器。
sio = socketio.AsyncServer(async_mode='sanic')
为aiohttp配置的服务器必须附加到现有的应用程序:
app = Sanic()
sio.attach(app)
本文暂时没有评论,来添加一个吧(●'◡'●)