From abba3fadf1c1f6c1200bd9af37d693bab6d16053 Mon Sep 17 00:00:00 2001 From: s_kiani Date: Wed, 19 Feb 2025 14:13:00 +0330 Subject: [PATCH] added hearbeat --- app.py | 75 ++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 60 insertions(+), 15 deletions(-) diff --git a/app.py b/app.py index 0291ac6..70edf1a 100755 --- a/app.py +++ b/app.py @@ -50,18 +50,22 @@ def handle_camera_status(status: int): # Helper class to track client connection status class ConnectionTracker: def __init__(self): - self.last_message_time = time.time() # Use time.time() to get the current time - self.timeout = 15 # Timeout in seconds (adjust as needed) - - def update_last_message_time(self): - self.last_message_time = time.time() # Update with the current time - - def is_client_connected(self): - return (time.time() - self.last_message_time) < self.timeout # Use time.time() - + self.last_message_time = time.time() + self.timeout = 30 # 30-second timeout + self.last_client_ip = None # Track last connected client IP + + def update_last_message_time(self, client_ip=None): + self.last_message_time = time.time() + if client_ip: + self.last_client_ip = client_ip # Update last known client + + def is_client_active(self): + """Check if the last client is still active within the last 30 seconds.""" + return (time.time() - self.last_message_time) < self.timeout # Create an instance of ConnectionTracker connection_tracker = ConnectionTracker() + class ConnectionThread(threading.Thread): def __init__(self): super().__init__() @@ -69,18 +73,55 @@ class ConnectionThread(threading.Thread): def run(self): while self.running: - if not connection_tracker.is_client_connected(): - print("Client disconnected. Searching for another client...") + + if connection_tracker.last_client_ip: + print(f"Checking if last client {connection_tracker.last_client_ip} is still available...") + + if self.query_last_client(connection_tracker.last_client_ip): + connection_tracker.update_last_message_time() + print(f"Last client {connection_tracker.last_client_ip} responded. Continuing...") + continue # Skip discovering a new client + if not connection_tracker.is_client_active(): + + + print("Client inactive for 30 seconds. Searching for another client...") cl_ip, _ = self.start_discovery_service(12345) - print(cl_ip) + print(f"New client found: {cl_ip}") # Reinitialize the Manager with the new client address global manager manager = Manager(f"tcp://{cl_ip}:5558", f"tcp://{cl_ip}:5557") - manager.start(manager_callback) # Restart the Manager and re-register the callback + manager.start(manager_callback) + + connection_tracker.update_last_message_time(cl_ip) # Update with new client + + def query_last_client(self, client_ip): + """Send a heartbeat packet to the last known client IP on port 29170 and wait for a response.""" + + print(f"Sending heartbeat to {client_ip}:29170") # Debugging + + sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + sock.settimeout(5) # 5-second timeout + heartbeat_port = 29170 # New port for heartbeat + + try: + sock.sendto(b"HEARTBEAT", (client_ip, heartbeat_port)) # Send heartbeat message + data, addr = sock.recvfrom(1024) # Wait for response + + print(f"Received response from {addr}: {data.decode()}") # Debugging + + if data.decode() == "HEARTBEAT_ACK": + print(f"Client {client_ip} is still responding.") + return True + + except socket.timeout: + print(f"Client {client_ip} did not respond. Marking as inactive.") + + finally: + sock.close() + + return False # Client did not respond - connection_tracker.update_last_message_time() # Reset the timer after reconnecting - time.sleep(10) # Check every 10 seconds def start_discovery_service(self, port): sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) @@ -95,9 +136,13 @@ class ConnectionThread(threading.Thread): break return addr + + + def stop(self): self.running = False + if __name__ == '__main__': QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling) app = QCoreApplication(sys.argv)