Home > OS >  Python Websockets handles one time use only
Python Websockets handles one time use only

Time:08-21

I want to make a python code that browsers can connect to get a video stream.

Problem is that my python code handles only one time use, meaning if you open the browser it will connect to that websocket correctly, but if you refresh the page, or another client want to access a stream from in parallel it doesn't work My code:

import asyncio
import websockets
import cv2
import os
import signal

async def time1(websocket, path):

    while True:
        
            vid = cv2.VideoCapture('V_DRONE_097.mp4')
            vid.set(cv2.CAP_PROP_FPS,24)
        
        try:
            #v = VideoStreamWidget()
            #v.ops()
            
            while(vid.isOpened()):
                
                img, frame = vid.read()
                
                #frame = cv2.resize(frame, (640, 480))
                encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), 65]
                man = cv2.imencode('.jpg', frame, encode_param)[1]
                #sender(man)
                #print(len(man.tobytes()))
                #cv2.imshow('img',man)
                await websocket.send(man.tobytes())
            
        except :
            pass

async def main():
    loop = asyncio.get_running_loop()
    stop = loop.create_future()
    #loop.add_signal_handler(signal.SIGTERM, stop.set_result, None)

    port = int(os.environ.get("PORT", "8585"))
    global stop1
    async with websockets.serve(time1, "", port):
        await stop
    stop1 = False
'''
async def main():
    async with websockets.serve(time1, "localhost", 8585):
        await asyncio.Future()  # run forever

asyncio.run(main())
'''
if __name__ == "__main__":
    while True:
        asyncio.run(main())

I want the server to keep working even if the client (browser) refreshes the page or close it and comeback later.

This is the code of javascript running in the browser if that will help:

openSocket = () => {

socket = new WebSocket("ws://127.0.0.1:8585/");
let msg = document.getElementById("msg");
socket.addEventListener('open', (e) => {
    document.getElementById("status").innerHTML = "Opened";
});
socket.addEventListener('message', (e) => {
    let ctx = msg.getContext("2d");
    let image = new Image();
    image.src = URL.createObjectURL(e.data);
    image.addEventListener("load", (e) => {
        ctx.drawImage(image, 0, 0, msg.width, msg.height);
    });
});
}

and this is the HTML code:

<!DOCTYPE html>
<html>
    <head>
        <title>Python_Websocket_Live_Streaming</title>
        <link rel="stylesheet" type="text/css" href="style.css">
        <script type="text/javascript" src="script.js" ></script>
    </head>
    <body onl oad="openSocket()">
        <div id="status">
            Connection failed. Somebody may be using the socket.
        </div>
        <div style="text-align: center">
            <canvas id="msg" width="960" height="720" style="display:inline-block" />
        </div>
        
    </body>
</html>

I've searched and tried many solutions but non worked. My final goal is to integrate this with flask API

Update 1: yes it is stuck in the time1 function I've known from wrapping the "send" function in a try catch:

try:
                            await websocket.send(man.tobytes())
except websockets.exceptions.ConnectionClosedError:
                            print("clean up")
                            break

when the browser closes/refresh the page, clean up is printed infinitely

Edit 2 It was stuck in the outer loop, that while true loop. Solved now Thanks

CodePudding user response:

There are a few culprits, but ultimately I think that while(vid.isOpened()) prevents the async from ever being free

edit

or stuck in the outer while loop

  • Related