我用这个包创建了 websocket server https://websockets.readthedocs.io/en/stable/intro.html 。我必须停止在运行时重新启动该服务器。
我的服务器作为 asyncio.Task 运行,但 cancel() 方法似乎什么也没做。 有什么方法可以停止此服务器任务,然后再次启动它吗?
server.py
#!/usr/bin/env python3
import asyncio
import websockets
class App:
def __init__(self):
self._task = None
self._slots = []
async def worker(self, websocket, path):
data = await websocket.recv()
self._slots.append(data)
await websocket.send(f'prev: {"; ".join(self._slots)}')
self.stop_server()
def start_server(self):
self._task = asyncio.ensure_future(websockets.serve(self.worker, 'localhost', 5000))
def stop_server(self):
self._task.cancel() # this doeas not stop server :P
print(self._task.cancelled()) # always False
def run(self):
try:
loop = asyncio.get_event_loop()
self.start_server()
loop.run_forever()
finally:
loop.close()
App().run()
测试客户端
#!/usr/bin/env python
# WS client example
import asyncio
import websockets
async def hello():
async with websockets.connect(
'ws://localhost:5000') as websocket:
name = input("What's your name? ")
await websocket.send(name)
print(f"> {name}")
greeting = await websocket.recv()
print(f"< {greeting}")
asyncio.get_event_loop().run_until_complete(hello())
最佳答案
在您提供的链接的“部署”部分下,有一个“正常关闭”部分: https://websockets.readthedocs.io/en/stable/deployment.html#graceful-shutdown
You may want to close connections gracefully when shutting down the server, perhaps after executing some cleanup logic. There are two ways to achieve this with the object returned by serve():
- using it as a asynchronous context manager, or
- calling its close() method, then waiting for its wait_closed() method to complete.
On Unix systems, shutdown is usually triggered by sending a signal.
Here’s a full example (Unix-only):
#!/usr/bin/env python
import asyncio
import signal
import websockets
async def echo(websocket, path):
async for message in websocket:
await websocket.send(message)
async def echo_server(stop):
async with websockets.serve(echo, "localhost", 8765):
await stop
loop = asyncio.get_event_loop()
# The stop condition is set when receiving SIGTERM.
stop = loop.create_future()
loop.add_signal_handler(signal.SIGTERM, stop.set_result, None)
# Run the server until the stop condition is met.
loop.run_until_complete(echo_server(stop))
请注意,上面只是一个 Unix 示例。
通过将 stop
可等待替换为以下内容,我在 Windows 上得到了同样的效果:
import threading
stop_event = threading.Event()
stop = asyncio.get_event_loop().run_in_executor(None, stop_event.wait)
然后当你想停止服务器时调用stop_event.set()
关于python - 如何停止使用 websockets.serve() 创建的 websocket 服务器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56663152/