Aditya Diwakar
Aditya Diwakar

Reputation: 180

Running background task for websockets in Python

I've started a project that requires and uses websockets to send information from server X to client Y, as intended.

However, I kept running into the issue where every 20 or so seconds the connection would be dropped since that's how TCP/IP is meant to be, so I need to send heartbeats per se.

Before I go on, if there's some other way of doing this (apart from sending a heartbeat) please let me know.


So the methodology I was going about to make the websocket before sending heartbeats was as such:

async def listener(websocket, path, service):
  command = service['log_command']
  p = subprocess.Popen(command, stdout=subprocess.PIPE, bufsize=1, shell=True)
  prev_sd = "-1"
  await heartbeat_manager(websocket)
  asyncio.sleep(5)
  while True:
    await websocket.send(p.stdout.readline())

The while True and after is all that we care about, my intention is to have the websocket send a heartbeat of some text every 5 seconds but don't know where at all to get started.

Sidenote: There's another function that I call that actually runs this websocket, but it's irrelevant to the question so I did not include it, but rest assured; it does exist (and all of this code is functional, but only for 20ish seconds before dying).

Upvotes: 1

Views: 4175

Answers (1)

rdv
rdv

Reputation: 51

Since you're using Python's async/await mechanism, perhaps you could try using asyncio subprocesses to let you await a subprocess's output streams. The following example code spawns the subprocess and checks for new lines available on standard output with a 5 second timeout, using asyncio.wait_for(); if no data is available to send, we deliver a heartbeat instead.

import asyncio

async def listener(websocket, path, service):
    command = service['log_command']
    p = await asyncio.create_subprocess_shell(command, stdout=asyncio.subprocess.PIPE)
    ...
    while True:
        try:
            data = await asyncio.wait_for(p.stdout.readline(), timeout=5)
            websocket.send(data)
        except asyncio.TimeOutError:
            await websocket.send("heartbeat")

Upvotes: 1

Related Questions