My django server serves a video feed, as a jpeg stream, one frame at a time.
It looks like this:
class VideoCamera():
def __init__(self):
# code
def get_frame(self):
# code
return frame
def gen(camera):
while True:
yield camera.get_frame()
def view_cam(request):
return StreamingHttpResponse(gen(VideoCamera()), content_type="multipart/x-mixed-replace;boundary=frame")
It's a live camera feed, so there's no end to the stream. I need it to be interrupted when the client disconnects, but so far, I can't figure out how to detect that a client disconnected.
Am I missing something?
Edit:
To eliminate anything to do with the camera, I did this:
def gen():
for i in range(1000):
time.sleep(1)
print(i)
yield i
def view_cam(request):
return StreamingHttpResponse(gen(), content_type="multipart/x-mixed-replace;boundary=frame")
and connected to my view with curl -N http://localhost/my_app/view_cam/
. It streams the numbers, and when I stop curl with Ctrl+C, the generator just keeps running indefinitely, not noticing that the client disappeared. If I run and stop curl a few more times, I have multiple instances of my gen()
function running, which is exactly what happens with the camera.
Edit 2:
This project uses Django Channels. I just noticed that if I disable channels by commenting it out in my settings.py, the above example works perfectly. I didn't think channels was related to the problem, but apparently, it is - somehow.
The channels development server does actually detect the disconnect after 10 seconds (not immediately like the default django server), and show this:
Application instance call() running at /home/pi/paperless_clipboard/venv3/lib/python3.5/site-packages/channels/http.py:213> wait_for=._call_check_cancel() at /usr/lib/python3.5/asyncio/futures.py:452, Task._wakeup()]>> for connection took too long to shut down and was killed.
but despite the message that something was killed, gen()
keeps running, printing numbers to the terminal.