@@ -32,30 +32,30 @@ class WebSocketCamera(BaseCamera):
3232 - JSON messages with image data
3333 """
3434
35- def __init__ (self , host : str = "0.0.0.0" , port : int = 8080 ,
36- frame_format : str = "base64" , max_queue_size : int = 10 , ** kwargs ):
35+ def __init__ (self , host : str = "0.0.0.0" , port : int = 8080 , timeout : int = 10 ,
36+ frame_format : str = "binary" , ** kwargs ):
3737 """
3838 Initialize WebSocket camera server.
3939
4040 Args:
41- host: Host address to bind the server to (default: "localhost ")
41+ host: Host address to bind the server to (default: "0.0.0.0 ")
4242 port: Port to bind the server to (default: 8080)
43- frame_format: Expected frame format from clients ("base64", "binary", "json")
44- max_queue_size: Maximum frames to buffer
43+ frame_format: Expected frame format from clients ("binary", "base64", "json") (default: "binary")
4544 **kwargs: Additional camera parameters
4645 """
4746 super ().__init__ (** kwargs )
4847
4948 self .host = host
5049 self .port = port
50+ self .timeout = timeout
5151 self .frame_format = frame_format
5252
53- self ._frame_queue = queue .Queue (maxsize = max_queue_size )
53+ self ._frame_queue = queue .Queue (1 )
5454 self ._server = None
5555 self ._loop = None
5656 self ._server_thread = None
5757 self ._stop_event = None
58- self ._client : Optional [websockets .WebSocketServerProtocol ] = None
58+ self ._client : Optional [websockets .ServerConnection ] = None
5959
6060 def _open_camera (self ) -> None :
6161 """Start the WebSocket server."""
@@ -67,9 +67,8 @@ def _open_camera(self) -> None:
6767 self ._server_thread .start ()
6868
6969 # Wait for server to start
70- timeout = 10.0
7170 start_time = time .time ()
72- while self ._server is None and time .time () - start_time < timeout :
71+ while self ._server is None and time .time () - start_time < self . timeout :
7372 if self ._server is not None :
7473 break
7574 time .sleep (0.1 )
@@ -92,20 +91,20 @@ def _start_server_thread(self) -> None:
9291 async def _start_server (self ) -> None :
9392 """Start the WebSocket server."""
9493 try :
95- # Create async stop event for this event loop
9694 self ._stop_event = asyncio .Event ()
9795
9896 self ._server = await websockets .serve (
9997 self ._ws_handler ,
10098 self .host ,
10199 self .port ,
100+ open_timeout = self .timeout ,
101+ ping_timeout = self .timeout ,
102+ close_timeout = self .timeout ,
102103 ping_interval = 20 ,
103- ping_timeout = 10
104104 )
105105
106106 logger .info (f"WebSocket camera server started on { self .host } :{ self .port } " )
107107
108- # Wait for stop event instead of busy loop
109108 await self ._stop_event .wait ()
110109
111110 except Exception as e :
@@ -116,26 +115,26 @@ async def _start_server(self) -> None:
116115 self ._server .close ()
117116 await self ._server .wait_closed ()
118117
119- async def _ws_handler (self , websocket : websockets .WebSocketServerProtocol ) -> None :
118+ async def _ws_handler (self , conn : websockets .ServerConnection ) -> None :
120119 """Handle a connected WebSocket client. Only one client allowed at a time."""
121- client_addr = f"{ websocket .remote_address [0 ]} :{ websocket .remote_address [1 ]} "
120+ client_addr = f"{ conn .remote_address [0 ]} :{ conn .remote_address [1 ]} "
122121
123122 if self ._client is not None :
124123 # Reject the new client
125124 logger .warning (f"Rejecting client { client_addr } : only one client allowed at a time" )
126125 try :
127- await websocket .send (json .dumps ({
126+ await conn .send (json .dumps ({
128127 "error" : "Server busy" ,
129128 "message" : "Only one client connection allowed at a time" ,
130129 "code" : 1000
131130 }))
132- await websocket .close (code = 1000 , reason = "Server busy - only one client allowed" )
131+ await conn .close (code = 1000 , reason = "Server busy - only one client allowed" )
133132 except Exception as e :
134133 logger .warning (f"Error sending rejection message to { client_addr } : { e } " )
135134 return
136135
137136 # Accept the client
138- self ._client = websocket
137+ self ._client = conn
139138 logger .info (f"Client connected: { client_addr } " )
140139
141140 try :
@@ -145,12 +144,14 @@ async def _ws_handler(self, websocket: websockets.WebSocketServerProtocol) -> No
145144 "status" : "connected" ,
146145 "message" : "You are now connected to the camera server" ,
147146 "frame_format" : self .frame_format ,
147+ "resolution" : self .resolution ,
148+ "fps" : self .fps ,
148149 })
149150 except Exception as e :
150151 logger .warning (f"Could not send welcome message to { client_addr } : { e } " )
151152
152153 warning_task = None
153- async for message in websocket :
154+ async for message in conn :
154155 frame = await self ._parse_message (message )
155156 if frame is not None :
156157 # Drop old frames until there's room for the new one
@@ -180,7 +181,7 @@ async def _ws_handler(self, websocket: websockets.WebSocketServerProtocol) -> No
180181 except Exception as e :
181182 logger .warning (f"Error handling client { client_addr } : { e } " )
182183 finally :
183- if self ._client == websocket :
184+ if self ._client == conn :
184185 self ._client = None
185186 logger .info (f"Client removed: { client_addr } " )
186187
0 commit comments