Issues listening incoming messages in websocket client on Python 3.6

发布于 2021-01-29 16:04:53

I’m trying to build a websocket client on Python using websockets
package from here: Websockets 4.0
API

I’m using this way instead of example code because I want to create a
websocket client class object, and use it as gateway.

I’m having issues with my listener method (receiveMessage) on client side,
which raises a ConnectionClose exception at execution. I think maybe there is
any problem with the loop.

This is the simple webSocket client I’ve tried to build:

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))

And this is the main:

'''
    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()

To test incoming messages listener, server sends two messages to client when
it stablishes the connection.

Client connects correctly to server, and sends the greeting. However, when
client receives both messages, it raises a ConnectionClosed exception with
code 1000 (no reason).

If I remove the loop in the receiveMessage client method, client does not
raise any exception, but it only receives one message, so I suppose I need a
loop to keep listener alive, but I don’t know exactly where or how.

Any solution?

Thanks in advance.

EDIT: I realize that client closes connection (and breaks loop) when it
receives all pending messages from server. However, I want client keeps alive
listening future messages.

In addition, I’ve tried to add another function whose task is to send a
‘heartbeat’ to server, but client closes connection anyway.

关注者
0
被浏览
48
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    Finally, based on this
    post answer, I modified my client and main files this
    way:

    WebSocket Client:

    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
    

    Main:

    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))
    

    Now, client keeps alive listening all messages from server and sending ‘ping’
    messages every 5 seconds to server.



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看