python - 如何停止使用 websockets.serve() 创建的 websocket 服务器?

标签 python websocket python-asyncio

我用这个包创建了 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/

相关文章:

javascript - websocket 客户端在发送大数据时断开连接

python Tornado SSLEOFError : EOF occurred in violation of protocol (_ssl. c:581)

http - 为什么我们在 websocket 握手响应中使用\n\r?

python - 异步和无限循环

python - 来自字典列表的 Pandas SparseDataFrame

python - 使用 openpyxl 保存更改

Python 从普通函数调用协程

python - CancelledError 异常处理程序未触发

python - 不断收到 AttributeError : 'list' object has no attribute 'split' error

python - 如何在没有副作用的情况下 pickle 和解 pickle ?