如何使用Python Websockets和Asyncio定期发送数据并等待接收数据但没有阻止发送过程

发布于 2025-02-09 09:29:19 字数 2188 浏览 4 评论 0原文

我已经搜索很长时间了,并且练习了一些,但是找不到解决方案。

这是我的目标:

  • 我想要一个偶尔将数据发送到我的服务器

    的JavaScript客户端
  • 我想定期(每秒左右)将数据发送给我的客户端。

这是我得到的:
我能够将数据发送给我的客户端并根据需要进行处理。
我能够将数据发送到我的服务器,但无法在服务器中接收它。这必须是一个非阻止过程,并且由于偶尔发送数据,因此我在服务器代码中实现此功能遇到了麻烦。

到目前为止,我的服务器代码是:

import asyncio
import random
import websockets
import json


async def recv(websocket, path):
    try:
        name = asyncio.wait_for(websocket.recv(), timeout=2)
    except TimeoutError:
        print("Time exceeded")
        name = None
    await asyncio.sleep(0.5)


async def send(websocket, path):
    data = [
            {
              "name": "Random Int 1",
              "number": random.randint(0, 1000)
            },
            {
              "name": "Random Int 2",
              "number": random.randint(1001, 2000)
            },
            {
              "name": "Random Int 3",
              "number": random.randint(2001, 3000)
            }
    ]
    await websocket.send(json.dumps(data))
    await asyncio.sleep(0.5)


async def main(websocket, path):
    while True:
        send_task = asyncio.create_task(send(websocket, path))
        recv_task = asyncio.create_task(recv(websocket, path))
        await send_task
        await recv_task

start_server = websockets.serve(main, "localhost", 3500)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()

我的错误是:

program.py:43: DeprecationWarning: There is no current event loop
  asyncio.get_event_loop().run_until_complete(start_server)
program.py:44: DeprecationWarning: There is no current event loop
  asyncio.get_event_loop().run_forever()
python3.10/asyncio/events.py:80: RuntimeWarning: coroutine 'wait_for' was never awaited
  self._context.run(self._callback, *self._args)
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
python3.10/asyncio/events.py:80: RuntimeWarning: coroutine 'WebSocketCommonProtocol.recv' was never awaited
  self._context.run(self._callback, *self._args)
RuntimeWarning: Enable tracemalloc to get the object allocation traceback

有任何提示吗? 多谢 !

I've Been searching for quite a long time now and practicing a bit but I can't find a solution.

Here's my goal:

  • I would like a Javascript Client that occasionally sends data to my server

  • I'd like a server (in Python) that periodically (every second or so) sends data to my client.

Here's what I've got:
I'm able to send data to my client and process it as I want.
I'm able to send data to my server but I'm not able to receive it in my Server. It has to be a non-blocking process and because the data is occasionally sent, I'm having trouble implementing this in my server code.

My server code so far is:

import asyncio
import random
import websockets
import json


async def recv(websocket, path):
    try:
        name = asyncio.wait_for(websocket.recv(), timeout=2)
    except TimeoutError:
        print("Time exceeded")
        name = None
    await asyncio.sleep(0.5)


async def send(websocket, path):
    data = [
            {
              "name": "Random Int 1",
              "number": random.randint(0, 1000)
            },
            {
              "name": "Random Int 2",
              "number": random.randint(1001, 2000)
            },
            {
              "name": "Random Int 3",
              "number": random.randint(2001, 3000)
            }
    ]
    await websocket.send(json.dumps(data))
    await asyncio.sleep(0.5)


async def main(websocket, path):
    while True:
        send_task = asyncio.create_task(send(websocket, path))
        recv_task = asyncio.create_task(recv(websocket, path))
        await send_task
        await recv_task

start_server = websockets.serve(main, "localhost", 3500)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()

my errors are:

program.py:43: DeprecationWarning: There is no current event loop
  asyncio.get_event_loop().run_until_complete(start_server)
program.py:44: DeprecationWarning: There is no current event loop
  asyncio.get_event_loop().run_forever()
python3.10/asyncio/events.py:80: RuntimeWarning: coroutine 'wait_for' was never awaited
  self._context.run(self._callback, *self._args)
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
python3.10/asyncio/events.py:80: RuntimeWarning: coroutine 'WebSocketCommonProtocol.recv' was never awaited
  self._context.run(self._callback, *self._args)
RuntimeWarning: Enable tracemalloc to get the object allocation traceback

Any tips ?
Thanks a lot !

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

逆光飞翔i 2025-02-16 09:29:19

尝试此服务器代码:

import asyncio
import random
import websockets
import json


async def handler(websocket):

    # create periodic task:
    asyncio.create_task(send(websocket))

    while True:
        try:
            message = await websocket.recv()
            print(message)

        # client disconnected?
        except websockets.ConnectionClosedOK:
            break


async def send(websocket):
    while True:
        data = [
            {"name": "Random Int 1", "number": random.randint(0, 1000)},
            {"name": "Random Int 2", "number": random.randint(1001, 2000)},
            {"name": "Random Int 3", "number": random.randint(2001, 3000)},
        ]

        try:
            await websocket.send(json.dumps(data))

        # client disconnected?
        except websockets.ConnectionClosedOK:
            break

        await asyncio.sleep(0.5)


async def main():
    async with websockets.serve(handler, "localhost", 3500):
        await asyncio.Future()  # run forever


if __name__ == "__main__":
    asyncio.run(main())

如何测试?

  • 在一个终端中运行此服务器代码,
  • 在另一个终端运行此Python代码:Python -M Websockets ws ws:// localhost:3500

您将立即看到服务器每0.5秒发送每0.5秒的随机JSON消息。
您可以输入一些消息,然后按Enter,然后查看该消息已在服务器屏幕上打印出来。
退出客户端按CTRL+D

Try this server code:

import asyncio
import random
import websockets
import json


async def handler(websocket):

    # create periodic task:
    asyncio.create_task(send(websocket))

    while True:
        try:
            message = await websocket.recv()
            print(message)

        # client disconnected?
        except websockets.ConnectionClosedOK:
            break


async def send(websocket):
    while True:
        data = [
            {"name": "Random Int 1", "number": random.randint(0, 1000)},
            {"name": "Random Int 2", "number": random.randint(1001, 2000)},
            {"name": "Random Int 3", "number": random.randint(2001, 3000)},
        ]

        try:
            await websocket.send(json.dumps(data))

        # client disconnected?
        except websockets.ConnectionClosedOK:
            break

        await asyncio.sleep(0.5)


async def main():
    async with websockets.serve(handler, "localhost", 3500):
        await asyncio.Future()  # run forever


if __name__ == "__main__":
    asyncio.run(main())

How to test it?

  • in one terminal run this server code
  • in other terminal run this python code: python -m websockets ws://localhost:3500

You will immediately see that the server sends every 0.5 seconds some random Json messages.
You can type some message and press enter and see that the message is printed in the server screen.
To exit client press Ctrl+D

二智少女 2025-02-16 09:29:19

看来我找到了一个工作解决方案,但不确定这是最好的...

这是我的代码:

import asyncio
import random
import websockets
import json


async def recv(websocket, path):
    try:
        name = await asyncio.wait_for(websocket.recv(), timeout=0.1) #I forgot the "await" \facepalm
        print("name", name)
    except asyncio.TimeoutError:
        print("No Data")
    await asyncio.sleep(0.1)

async def send(websocket, path):
    data = [
            {
              "name": "Random Int 1",
              "number": random.randint(0, 1000)
            },
            {
              "name": "Random Int 2",
              "number": random.randint(1001, 2000)
            },
            {
              "name": "Random Int 3",
              "number": random.randint(2001, 3000)
            }
    ]
    await websocket.send(json.dumps(data))
    await asyncio.sleep(0.1)


async def main2(websocket, path):
    while True:
        send_task = asyncio.create_task(send(websocket, path))
        await send_task
        recv_task = asyncio.create_task(recv(websocket, path))
        await recv_task

#rewrite of this part is to remove Deprecation Warning
async def main():
    server = await websockets.serve(main2, 'localhost', 3500)
    await server.wait_closed()

asyncio.run(main())

It seems that I found a working solution but not sure that this is the best...

Here's my code:

import asyncio
import random
import websockets
import json


async def recv(websocket, path):
    try:
        name = await asyncio.wait_for(websocket.recv(), timeout=0.1) #I forgot the "await" \facepalm
        print("name", name)
    except asyncio.TimeoutError:
        print("No Data")
    await asyncio.sleep(0.1)

async def send(websocket, path):
    data = [
            {
              "name": "Random Int 1",
              "number": random.randint(0, 1000)
            },
            {
              "name": "Random Int 2",
              "number": random.randint(1001, 2000)
            },
            {
              "name": "Random Int 3",
              "number": random.randint(2001, 3000)
            }
    ]
    await websocket.send(json.dumps(data))
    await asyncio.sleep(0.1)


async def main2(websocket, path):
    while True:
        send_task = asyncio.create_task(send(websocket, path))
        await send_task
        recv_task = asyncio.create_task(recv(websocket, path))
        await recv_task

#rewrite of this part is to remove Deprecation Warning
async def main():
    server = await websockets.serve(main2, 'localhost', 3500)
    await server.wait_closed()

asyncio.run(main())
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文