python:websocket主动发消息,并接受消息

python 使用websocket为什么我能主动发 就不能收哎 await send(websocket)可以,再加上await rev()就不行了

clients = set()

newValue = ''
oldValue = ''
msg = ''

# 读串口


async def readLoop():
    global newValue
    print('开始读串口')
    port = "COM3"  # 修改为自己的串口
    bps = 9600
    bytesize = 8
    ser = serial.Serial(port, int(bps), int(bytesize),
                        timeout=1, parity=serial.PARITY_NONE, stopbits=1)
    while True:
        buffer = await asyncio.to_thread(ser.readline)  # 异步读取串口数据
        buffer = buffer.decode().strip()
        print(buffer)
        if buffer == '':
            continue
        if buffer == 'a':
            newValue = 'a'
        elif buffer == 'b':
            newValue = 'b'


# WebSocket 服务器
async def eho(websocket, path):
    global newValue, oldValue, clients
    # clients.clear()
    clients.add(websocket)
    print(len(clients), newValue, oldValue)

    await send(websocket)
    await rev(websocket)
     

# 发消息
async def send(websocket):
    global newValue, oldValue
    while True:
        if newValue != oldValue:
            websockets.broadcast(clients, newValue)
            oldValue = newValue
        else:
            await asyncio.sleep(random.random() * 1)

# 接收消息
async def rev(websocket):
    global msg
    while True:
        msg = await websocket.recv()
        print(msg)

    # 主函数


def main():
    t1 = Thread(target=lambda: asyncio.run(readLoop()))  # 在新线程中异步执行readLoop函数
    t1.start()
    start_server = websockets.serve(eho, "127.0.0.1", 5678)
    print('Websocket 服务器已启动')
    try:
        asyncio.get_event_loop().run_until_complete(start_server)
        asyncio.get_event_loop().run_forever()
    except KeyboardInterrupt:
        print('程序已结束')
        t1.join()  # 关闭线程


该回答引用ChatGPT

如有疑问,可以回复我!

根据你提供的代码,我发现在 eho 函数中,你调用了 await send(websocket) 和 await rev(websocket),但是你并没有对 rev 函数进行任何处理,它会一直在一个无限循环中等待接收消息,导致后面的代码无法执行。

你可以将 rev 函数放在另一个协程中,并在 eho 函数中使用 asyncio.gather 并发运行两个协程,代码示例如下:


async def eho(websocket, path):
    global newValue, oldValue, clients
    clients.add(websocket)
    print(len(clients), newValue, oldValue)

    await asyncio.gather(send(websocket), rev(websocket))  # 并发运行两个协程

此外,你在 readLoop 函数中异步读取串口数据,但是你并没有对 newValue 进行任何修改,导致在 send 函数中 newValue 始终为初始值。你可以在 readLoop 函数中修改 newValue 的值,使其可以正确地被 send 函数使用。

最后,你在 send 函数中使用了 websockets.broadcast(clients, newValue),但是在代码中没有看到 websockets 模块的导入。你需要在代码的开头添加 import websockets。

你的rev函数陷入了死循环,导致无法接收WebSocket的消息。在rev函数中,你使用了一个while True的循环,但没有任何退出循环的逻辑。因此,当代码执行到await websocket.recv()时,程序会一直阻塞在这里,无法继续往下执行。

为了解决这个问题,可以在rev函数中添加一个退出循环的条件,比如使用一个标志变量来控制循环的退出。例如,你可以在全局变量msg中存储接收到的消息,当msg中有值时,退出循环。代码示例如下:

async def rev(websocket):
    global msg
    while not msg:
        msg = await websocket.recv()
    print(msg)


这里,while not msg表示只要msg中没有值,就一直循环,直到接收到WebSocket的消息后,将msg的值更新为接收到的消息,循环就会自动退出。这样,你就可以正确地接收WebSocket的消息了。

参考GPT和自己的思路,在您的代码中,rev协程函数有一个无限循环,它会阻塞事件循环,防止进一步执行代码。为了解决这个问题,您可以修改rev函数以处理接收到的消息并在websocket关闭时返回。以下是修改后的代码:

clients = set()
 
newValue = ''
oldValue = ''
msg = ''
 
# 读串口
async def readLoop():
    global newValue
    print('开始读串口')
    port = "COM3"  # 修改为自己的串口
    bps = 9600
    bytesize = 8
    ser = serial.Serial(port, int(bps), int(bytesize),
                        timeout=1, parity=serial.PARITY_NONE, stopbits=1)
    while True:
        buffer = await asyncio.to_thread(ser.readline)  # 异步读取串口数据
        buffer = buffer.decode().strip()
        print(buffer)
        if buffer == '':
            continue
        if buffer == 'a':
            newValue = 'a'
        elif buffer == 'b':
            newValue = 'b'
 
 
# WebSocket 服务器
async def eho(websocket, path):
    global newValue, oldValue, clients
    clients.add(websocket)
    print(len(clients), newValue, oldValue)
 
    await send(websocket)
 
# 发消息
async def send(websocket):
    global newValue, oldValue
    while True:
        if newValue != oldValue:
            websockets.broadcast(clients, newValue)
            oldValue = newValue
        else:
            await asyncio.sleep(random.random() * 1)
 
# 接收消息
async def rev(websocket):
    global msg
    try:
        while True:
            msg = await websocket.recv()
            print(msg)
            # process received message
    except websockets.exceptions.ConnectionClosed:
        pass
 
# 主函数
def main():
    t1 = Thread(target=lambda: asyncio.run(readLoop()))  # 在新线程中异步执行readLoop函数
    t1.start()
    start_server = websockets.serve(eho, "127.0.0.1", 5678)
    print('Websocket 服务器已启动')
    try:
        asyncio.get_event_loop().run_until_complete(start_server)
        asyncio.get_event_loop().run_forever()
    except KeyboardInterrupt:
        print('程序已结束')
        t1.join()  # 关闭线程

回答不易,还请采纳!!!

参考GPT和自己的思路:在您的代码中,您已经使用了 await websocket.recv() 接收 WebSocket 的消息。但是,您的代码中有一个问题:您的代码陷入了一个无限循环。因此,当您接收到一个消息时,代码不会做任何事情,而只是继续等待下一条消息。为了解决这个问题,您应该将 await websocket.recv() 放在一个无限循环中,并在循环内对消息进行处理。

以下是修改后的 rev 函数的示例代码:

async def rev(websocket):
    global msg
    while True:
        msg = await websocket.recv()
        print(msg)

        # 这里可以对接收到的消息进行处理,例如回复一个消息
        response = "You said: " + msg
        await websocket.send(response)


这个函数将无限循环并等待新的消息。当您收到一条消息时,您可以在函数中对其进行处理,例如向客户端发送一个响应消息。

请注意,WebSocket 是一个异步通信协议。这意味着您必须使用 await 来等待接收到消息,否则您的代码将阻塞并且无法继续执行。同样,您必须使用 await 来等待将消息发送到 WebSocket,以确保它被成功发送。

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
在WebSocket服务器中接收消息,应该使用await websocket.recv()来接收消息,而不是在一个while循环中await。因为使用while循环会导致代码永远无法到达后面的代码。以下是修改后的代码:

import asyncio
import random
import serial
import websockets

clients = set()
newValue = ''
oldValue = ''
msg = ''

# 读串口
async def readLoop():
    global newValue
    print('开始读串口')
    port = "COM3"  # 修改为自己的串口
    bps = 9600
    bytesize = 8
    ser = serial.Serial(port, int(bps), int(bytesize),
                        timeout=1, parity=serial.PARITY_NONE, stopbits=1)
    while True:
        buffer = await asyncio.to_thread(ser.readline)  # 异步读取串口数据
        buffer = buffer.decode().strip()
        print(buffer)
        if buffer == '':
            continue
        if buffer == 'a':
            newValue = 'a'
        elif buffer == 'b':
            newValue = 'b'


# WebSocket 服务器
async def eho(websocket, path):
    global newValue, oldValue, clients
    clients.add(websocket)
    print(len(clients), newValue, oldValue)

    await send(websocket)
    await rev(websocket)

# 发消息
async def send(websocket):
    global newValue, oldValue
    while True:
        if newValue != oldValue:
            await websockets.broadcast(clients, newValue)
            oldValue = newValue
        else:
            await asyncio.sleep(random.random() * 1)

# 接收消息
async def rev(websocket):
    global msg
    while True:
        msg = await websocket.recv()
        print(msg)

# 主函数
def main():
    t1 = Thread(target=lambda: asyncio.run(readLoop()))  # 在新线程中异步执行readLoop函数
    t1.start()
    start_server = websockets.serve(eho, "127.0.0.1", 5678)
    print('Websocket 服务器已启动')
    try:
        asyncio.get_event_loop().run_until_complete(start_server)
        asyncio.get_event_loop().run_forever()
    except KeyboardInterrupt:
        print('程序已结束')
        t1.join()  # 关闭线程

if __name__ == '__main__':
    main()

需要注意的是,websockets.broadcast(clients, newValue)需要使用await来发送消息。另外,您似乎没有在rev函数中使用接收到的消息msg,因此可以将其删除。
如果我的回答解决了您的问题,请采纳!

在使用Python中的WebSocket时,可能会遇到无法同时发送和接收消息的问题。这可能是由于WebSocket的工作方式导致的,WebSocket是基于异步IO的技术,消息的发送和接收都需要通过异步IO的方式来实现。

在使用Python的WebSocket时,通常会使用asyncio库来实现异步IO的功能。在发送和接收消息时,需要使用async with来创建一个WebSocket连接,并使用await关键字来发送和接收消息。示例代码如下:

import asyncio
import websockets

async def send_and_receive():
    async with websockets.connect('ws://localhost:8765') as websocket:
        await websocket.send('Hello, World!')
        response = await websocket.recv()
        print(response)

asyncio.run(send_and_receive())


在以上示例代码中,async with语句创建了一个WebSocket连接,await websocket.send()语句发送了一条消息,await websocket.recv()语句接收了一条消息。需要注意的是,在async with语句中,WebSocket连接是异步上下文管理器,需要使用async with语句来创建并管理连接。

如果您遇到了无法同时发送和接收消息的问题,可能是由于程序中存在死锁或阻塞操作,导致程序无法继续执行。建议您检查代码中是否存在死锁或阻塞操作,或者尝试使用更加详细的代码示例来说明您遇到的问题。

不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^