python-3.x - 无法停止 aiohttp websocket 服务器
问题描述
我无法从应用程序中取消我的 aiohttp websocket 服务器。当我从客户端获得“取消”字符串时,我想停止服务器并关闭。是的,我明白了,我完成了我的协同程序(websocket_handler),但是来自 aiohttp 库的三个协同程序仍在继续工作。
当然,我可以asyncio.get_event_loop().stop()
在我的协程结束时调用,但是有没有一种优雅的方式来停止 aiohttp 服务器?
从我的代码中可以看出我尝试过使用 Application().on_shutdown.append()
,但失败了。
什么是正确的方法?
#!/usr/bin/env python # - - 编码:utf-8 - - import os import asyncio import signal import weakref
import aiohttp.web
from aiohttp import ClientConnectionError, WSCloseCode
# This restores the default Ctrl+C signal handler, which just kills the process
#https://stackoverflow.com/questions/27480967/why-does-the-asyncios-event-loop-suppress-the-keyboardinterrupt-on-windows
import signal
signal.signal(signal.SIGINT, signal.SIG_DFL)
HOST = os.getenv('HOST', 'localhost')
PORT = int(os.getenv('PORT', 8881))
async def testhandle(request):
#Сопрограмма одрабатывающая http-запрос по адресу "http://127.0.0.1:8881/test"
print("server: into testhandle()")
return aiohttp.web.Response(text='Test handle')
async def websocket_handler(request):
#Сопрограмма одрабатывающая ws-запрос по адресу "http://127.0.0.1:8881"
print('Websocket connection starting')
ws = aiohttp.web.WebSocketResponse()
await ws.prepare(request)
request.app['websockets'].add(ws)
print('Websocket connection ready')
try:
async for msg in ws:
if msg.type == aiohttp.WSMsgType.TEXT:
if msg.data == 'close':
print(msg.data)
break
else:
print(msg.data)
await ws.send_str("You said: {}".format(msg.data))
elif msg.type == aiohttp.WSMsgType.ERROR:
print('ws connection closed with exception %s' %
ws.exception())
except (asyncio.CancelledError, ClientConnectionError):
pass # Тут оказываемся когда, клиент отвалился.
# В будущем можно тут освобождать ресурсы.
finally:
print('Websocket connection closed')
request.app['websockets'].discard(ws)
#pending = asyncio.Task.all_tasks()
#asyncio.get_event_loop().stop()
return ws
async def on_shutdown(app):
for ws in set(app['websockets']):
await ws.close(code=WSCloseCode.GOING_AWAY, message='Server shutdown')
def main():
loop = asyncio.get_event_loop()
app = aiohttp.web.Application()
app['websockets'] = weakref.WeakSet()
app.on_shutdown.append(on_shutdown)
app.add_routes([aiohttp.web.get('/', websocket_handler)]) #, aiohttp.web.get('/test', testhandle)
try:
aiohttp.web.run_app(app, host=HOST, port=PORT, handle_signals=True)
print("after run_app")
except Exception as exc:
print ("in exception")
finally:
loop.close()
if __name__ == '__main__':
main()
解决方案
https://docs.aiohttp.org/en/v3.0.1/web_reference.html#aiohttp.web.Application.shutdown
app.shutdown()
app.cleanup()
关机后你还应该做 cleanup()
推荐阅读
- jquery - jQuery点击功能阻止ajax请求
- python - 从目录动态创建python模块
- c# - 有没有办法在使用 Jint.NET 时切换环境?
- flutter - Flutter 版本升级后的 Hero on Tab 行为
- python - How can I save all my produced permutations into a Numpy array?
- git - Composer - 在 DockerFile 中使用用户名和密码(无 SSH 密钥)在管道上克隆 Git 存储库(Bitbucket)
- html - 在 React 中的 div 组件上设置背景图像时,如何检测断开的链接?
- javascript - How to access a constant nested function's parameter in javascript?
- c# - 从另一个进程接收消息
- r - 使用 tree_layout() 获取无根树的结构