开发者

Making pycurl request in asyncio websocket server setup

开发者 https://www.devze.com 2022-12-07 20:54 出处:网络
Currently, I have a simple websocket server that can handle recv and send operations. The code is as such.

Currently, I have a simple websocket server that can handle recv and send operations. The code is as such.

async def recv_handler(websocket):
    while True:
        try:
            message = await websocket.recv()
            print(message)
        except Exception as e:
            print(e)
        await asyncio.sleep(0.01)

async def send_handler(websocket):
    while True:
        try:
            data = {
                "type&qu开发者_运维百科ot;: "send",
                "time": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            }
            await websocket.send(json.dumps(data))
        except Exception as e:
            print(e)
        await asyncio.sleep(0.01)

async def main(websocket):
    while True:
        recv_task = asyncio.create_task(recv_handler(websocket))
        send_task = asyncio.create_task(send_handler(websocket))
        await asyncio.gather(recv_task, send_task)


async def start_server():
    server = await websockets.serve(main, "", 3001)
    await server.wait_closed()

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

This successfully runs a server, hand can handle message sent from a client node.js application using websockets as well as send updates to the client node.js application periodically.

 // receive a message from the server
  socket.addEventListener("message", ({ data }) => {
    const packet = JSON.parse(data);
    switch (packet.type) {
      case "send":
        console.log(packet.time)
        break;        
      default:
        break;
    }
  });

  // send message to server
  const onClickSend = () => {
    if (socket.readyState !== WebSocket.OPEN) {
      console.log("socket not open");
      return;
    } else {
      socket.send(JSON.stringify({
        type: "hello from client",
      }));
    }
  }

Now, I want to include a blocking function call that sends a pycurl (or any http) request, then use the result of that pycurl request, package it into the json object, and send that to the client.

I have a sample pycurl requst that gets the weather from wttr.in


def getWeather():
    # Creating a buffer as the cURL is not allocating a buffer for the network response
    buffer = BytesIO()
    c = pycurl.Curl()
    #initializing the request URL
    c.setopt(c.URL, 'wttr.in/Beijing?format="%l:+\%c+%t+%T\\n"')
    #setting options for cURL transfer  
    c.setopt(c.WRITEDATA, buffer)
    #setting the file name holding the certificates
    c.setopt(c.CAINFO, certifi.where())
    # perform file transfer
    c.perform()
    #Ending the session and freeing the resources
    c.close()

    #retrieve the content BytesIO
    body = buffer.getvalue()
    #decoding the buffer 
    return body.decode('utf-8')

So if we change data to include or weather,

date = {
   "type" : "send",
   "weather" : getWeather(), 
}

and we can slightly change the node.js application case statement to print

case "send":
   console.log(packet.weather)

The problem with this, I believe, is that we are making a blocking request, but I don't know enough on how to fix the problem. Currently, I can make requests, but every time the "onClickSend" is called (by pressing a button in frontend", now, we get an error saying that the "socket not open", meaning the backend is no longer handling receive messages.

So how do I handle pycurl requests in asyncio-websocket program?

0

精彩评论

暂无评论...
验证码 换一张
取 消