使用异步同时运行的两个协程

问题描述 投票:0回答:1

我正在尝试制作一个程序,该程序可以通过websocket读取数据以及从服务器发送和接收数据。目标是创建同步灯,其中有两个客户端灯和一个服务器。当其中一个灯更改状态时,它将向服务器发送请求,而服务器会更新另一个灯。我目前停留在客户端代码上。我可以与服务器建立Websocket连接,读取数据并将其发送到服务器,并且可以读取轻量数据。我在同时运行这两个任务时遇到问题。我想异步执行此操作以避免竞争条件问题。我正在使用python 3.8和asyncio。

到目前为止是我的websocket客户端代码:

async def init_connection(message):
  global CONNECTION_OPEN
  global CLIENT_WS
  uri = WS_URI
  async with websockets.connect(uri) as websocket:
      CONNECTION_OPEN = True
      CLIENT_WS = websocket
      # send init message
      await websocket.send(message)
      while CONNECTION_OPEN:
          await handleMessages(websocket, message)
      await websocket.send(json.dumps({'type': MessageType.Close.name, 'message': USERNAME}))
      await websocket.close()

到目前为止,这是我读到的数据代码:

async def calculate_idle(t):
  global STATE
  global prevColor
  x_arr = []
  y_arr = []
  z_arr = []
  while t >= 0:
     x, y, z = lis3dh.acceleration
     print("Current colors")
     print(accel_to_color(x,y,z))
     x_arr.append(x)
     y_arr.append(y)
     z_arr.append(z)
     newColor = accel_to_color(x,y,z)
     # remember prev color
     do_fade(prevColor, newColor)
     #strip.fill((int(a_x), int(a_y), int(a_z), 0))
     #strip.show()
     prevColor = newColor
     time.sleep(.2)
     t -= .2
  is_idle = is_lamp_idle(np.std(x_arr), np.std(y_arr), np.std(z_arr))

  if is_idle and STATE == "NOT IDLE" and CONNECTION_OPEN:
      STATE = "IDLE"
      print("Sending color")
      await asyncio.sleep(1)
  elif is_idle and CONNECTION_OPEN:
      # Check for data
      STATE = "IDLE"
      print ("Receiving data")
      await asyncio.sleep(1)
  elif is_idle and not CONNECTION_OPEN:
     print ("Idle and not connected")
      rainbow_cycle(0.001)    # rainbow cycle with 1ms delay per step
      await asyncio.sleep(1)
  else:
      STATE = "NOT IDLE"
      await asyncio.sleep(1)
      print("Is not idle")

这里是应该将它们绑在一起的代码:

async def main():
    message = json.dumps({'type': "authentication", 'payload': {
                            'username': 'user1', 'secret': SHARED_SECRET}})
    loop = asyncio.get_event_loop()
    start_light = asyncio.create_task(calculate_idle(3))
    await asyncio.gather(init_connection(message), start_light)
asyncio.run(main())

[还有其他功能,但前提是存在一个用于发送和接收数据的websocket连接,以及另一个读取轻量数据的进程。我还需要能够读取灯光的当前状态并设置灯光的当前状态,这就是我使用全局变量的原因。当前,它将读取灯光,直到它在计算空闲时碰到一个等待asyncio.sleep(1),然后切换到websocket代码并挂起从服务器接收数据。理想情况下,它将在读取当前状态和检查Websocket消息之间交替进行。如果状态发生变化,它将发送一个websocket消息。

我如何异步运行这两个例程并在它们之间共享数据?任何帮助表示赞赏!

python-3.x asynchronous websocket python-asyncio
1个回答
0
投票

感谢user4815162342的评论有助于缩小问题的范围。我的计算空闲时间没有那么长,我将time.sleep(.2)更改为等待asyncio.sleep(.2),我能够同时从服务器和电灯中读取数据。

© www.soinside.com 2019 - 2024. All rights reserved.