代码之家  ›  专栏  ›  技术社区  ›  CharlieHollow

在Python 3.6上的websocket客户端中侦听传入消息的问题

  •  13
  • CharlieHollow  · 技术社区  · 7 年前

    我想建立一个 websocket 客户端打开 python 从这里使用websockets软件包: Websockets 4.0 API

    我使用这种方式而不是示例代码,因为我想创建一个websocket客户端类对象,并将其用作网关。

    客户端的侦听器方法(receiveMessage)有问题,这会在执行时引发ConnectionClose异常。我想这个环路可能有问题。

    这是我尝试构建的简单webSocket客户端:

    import websockets
    
    class WebSocketClient():
    
        def __init__(self):
            pass
    
        async def connect(self):
            '''
                Connecting to webSocket server
    
                websockets.client.connect returns a WebSocketClientProtocol, which is used to send and receive messages
            '''
            self.connection = await websockets.client.connect('ws://127.0.0.1:8765')
            if self.connection.open:
                print('Connection stablished. Client correcly connected')
                # Send greeting
                await self.sendMessage('Hey server, this is webSocket client')
                # Enable listener
                await self.receiveMessage()
    
    
        async def sendMessage(self, message):
            '''
                Sending message to webSocket server
            '''
            await self.connection.send(message)
    
        async def receiveMessage(self):
            '''
                Receiving all server messages and handling them
            '''
            while True:
                message = await self.connection.recv()
                print('Received message from server: ' + str(message))
    

    这是主要的:

    '''
        Main file
    '''
    
    import asyncio
    from webSocketClient import WebSocketClient
    
    if __name__ == '__main__':
        # Creating client object
        client = WebSocketClient()
        loop = asyncio.get_event_loop()
        loop.run_until_complete(client.connect())
        loop.run_forever()
        loop.close()
    

    为了测试传入消息侦听器,服务器在建立连接时向客户端发送两条消息。

    客户端正确连接到服务器,并发送问候语。然而,当客户端同时收到这两条消息时,它会引发 ConnectionClosed异常 代码为1000(无原因)。

    如果我在receiveMessage客户机方法中删除循环,客户机不会引发任何异常,但它只接收一条消息,所以我想我需要一个循环来保持监听器的活动,但我不知道具体在哪里或如何。

    有什么解决方案吗?

    提前谢谢。

    编辑: 我意识到,当客户端从服务器接收到所有挂起的消息时,它会关闭连接(并中断循环)。然而,我希望客户端能够继续监听未来的消息。

    此外,我尝试添加另一个函数,其任务是向服务器发送“心跳信号”,但客户端无论如何都会关闭连接。

    1 回复  |  直到 7 年前
        1
  •  21
  •   CharlieHollow    7 年前

    最后,基于此 post 回答:我这样修改了我的客户端和主文件:

    WebSocket客户端:

    import websockets
    import asyncio
    
    class WebSocketClient():
    
        def __init__(self):
            pass
    
        async def connect(self):
            '''
                Connecting to webSocket server
    
                websockets.client.connect returns a WebSocketClientProtocol, which is used to send and receive messages
            '''
            self.connection = await websockets.client.connect('ws://127.0.0.1:8765')
            if self.connection.open:
                print('Connection stablished. Client correcly connected')
                # Send greeting
                await self.sendMessage('Hey server, this is webSocket client')
                return self.connection
    
    
        async def sendMessage(self, message):
            '''
                Sending message to webSocket server
            '''
            await self.connection.send(message)
    
        async def receiveMessage(self, connection):
            '''
                Receiving all server messages and handling them
            '''
            while True:
                try:
                    message = await connection.recv()
                    print('Received message from server: ' + str(message))
                except websockets.exceptions.ConnectionClosed:
                    print('Connection with server closed')
                    break
    
        async def heartbeat(self, connection):
            '''
            Sending heartbeat to server every 5 seconds
            Ping - pong messages to verify connection is alive
            '''
            while True:
                try:
                    await connection.send('ping')
                    await asyncio.sleep(5)
                except websockets.exceptions.ConnectionClosed:
                    print('Connection with server closed')
                    break
    

    主要内容:

    import asyncio
    from webSocketClient import WebSocketClient
    
    if __name__ == '__main__':
        # Creating client object
        client = WebSocketClient()
        loop = asyncio.get_event_loop()
        # Start connection and get client connection protocol
        connection = loop.run_until_complete(client.connect())
        # Start listener and heartbeat 
        tasks = [
            asyncio.ensure_future(client.heartbeat(connection)),
            asyncio.ensure_future(client.receiveMessage(connection)),
        ]
    
        loop.run_until_complete(asyncio.wait(tasks))
    

    现在,客户端保持活动状态,侦听来自服务器的所有消息,并每5秒向服务器发送“ping”消息。