Reputation: 180
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
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