在 Python 3.6 上的 websocket 客户端中侦听传入消息的问题 [英] Issues listening incoming messages in websocket client on Python 3.6

查看:42
本文介绍了在 Python 3.6 上的 websocket 客户端中侦听传入消息的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用来自此处的 websockets 包在 Python 上构建 websocket 客户端:Websockets 4.0 API

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

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

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

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

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.

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

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

这是主要的:

'''
    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.

客户端正确连接到服务器,并发送问候语.但是,当客户端收到两条消息时,它会引发代码为 1000(无缘无故)的 ConnectionClosed 异常.

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

如果我在receiveMessage客户端方法中删除循环,客户端不会引发任何异常,但它只接收一条消息,所以我想我需要一个循环来保持侦听器活着,但我不知道确切的位置或方式.

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.

有什么解决办法吗?

提前致谢.

我意识到客户端在收到来自服务器的所有待处理消息时会关闭连接(并中断循环).但是,我希望客户端保持活动状态,收听未来的消息.

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.

推荐答案

最后基于这个post 答案,我以这种方式修改了我的客户端和主文件:

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

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' 消息.

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

这篇关于在 Python 3.6 上的 websocket 客户端中侦听传入消息的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆