0

I'm currently struggling with something "simple". I'd like to have a python WebSocket Server, which is capable of closing down by outside events (e.g. a Ctrl+C from the command line).

Here is my code so far:

PORT = 8765

class Server(object):

    def __init__(self):
        self.online_players = dict()
        self.online_players_lock = asyncio.Lock()
        self.websocket_server = None

    async def add_online_player(self, id, player):
        async with self.online_players_lock:
            self.online_players[id] = player

    async def remove_online_player(self, id):
        async with self.online_players_lock:
            if id in self.online_players.keys():
                del self.online_players[id]

    def start(self):
        end = False
        loop = asyncio.new_event_loop()
        thread = threading.Thread(target=listen, args=(loop, self))
        thread.start()
        while not end:
            try:
                time.sleep(500)
            except KeyboardInterrupt:
                end = True
        loop.call_soon_threadsafe(stop_listening, loop, server)


async def on_connect(websocket, path, server):
    print("New user...")
    id = await websocket.recv()
    player = WebSocketPlayer(id, websocket, server)
    await server.add_online_player(id, player)
    # from this point on WebSocketPlayer class handles communication
    await player.listen()

def listen(loop, server:Server):
    asyncio.set_event_loop(loop)
    bound_handler = functools.partial(on_connect, server=server)
    start_server_task = websockets.serve(bound_handler, "localhost", PORT, ping_timeout=None, loop=loop)
    start_server = loop.run_until_complete(start_server_task)
    server.websocket_server = start_server
    print("Server running ...")
    loop.run_forever()

async def stop_listening(loop, server:Server):
    await server.websocket_server.wait_close()
    loop.stop()
    loop.close()


if __name__ == "__main__":
    server = Server()
    server.start()

Signal handlers from asyncio like loop.add_signal_handler(signum, callback, *args) are not an option for me, because they only work on Unix.

The error that I currently get is that the stop_listening method was never awaited, which kind of makes sense to me. So I am not that much interested in fixing my code example, but more in general how is it possible to achieve my goal, or how is it usually solved?

Thank you very much in advance

Sebastian
  • 143
  • 9

1 Answers1

0

Nevermind, this question is related to this question: Why does the asyncio's event loop suppress the KeyboardInterrupt on Windows? which is actually bug of asyncio on Windows.

Sebastian
  • 143
  • 9