Add reconnect logic for desktop app
This commit is contained in:
@@ -49,7 +49,9 @@ class VlcSyncApp(QMainWindow):
|
|||||||
|
|
||||||
self.sync_client = SyncClientThread("wss://video-sync.peterstockings.com/ws")
|
self.sync_client = SyncClientThread("wss://video-sync.peterstockings.com/ws")
|
||||||
self.sync_client.connected.connect(self.on_ws_connected)
|
self.sync_client.connected.connect(self.on_ws_connected)
|
||||||
|
self.sync_client.disconnected.connect(self.on_ws_disconnected)
|
||||||
self.sync_client.room_joined.connect(self.on_room_joined)
|
self.sync_client.room_joined.connect(self.on_room_joined)
|
||||||
|
self.sync_client.room_rejoined.connect(self.on_room_rejoined)
|
||||||
self.sync_client.room_error.connect(self.on_room_error)
|
self.sync_client.room_error.connect(self.on_room_error)
|
||||||
self.sync_client.file_check_needed.connect(self.on_file_check_needed)
|
self.sync_client.file_check_needed.connect(self.on_file_check_needed)
|
||||||
self.sync_client.users_updated.connect(self.on_users_updated)
|
self.sync_client.users_updated.connect(self.on_users_updated)
|
||||||
@@ -458,6 +460,18 @@ class VlcSyncApp(QMainWindow):
|
|||||||
if self.pending_connect_action:
|
if self.pending_connect_action:
|
||||||
self.pending_connect_action()
|
self.pending_connect_action()
|
||||||
self.pending_connect_action = None
|
self.pending_connect_action = None
|
||||||
|
elif self.stacked_widget.currentIndex() == 1 and self.room_code and self.username:
|
||||||
|
# We are already in a room and just reconnected
|
||||||
|
self.sync_client.send_message({
|
||||||
|
"type": "rejoin_room",
|
||||||
|
"username": self.username,
|
||||||
|
"code": self.room_code
|
||||||
|
})
|
||||||
|
|
||||||
|
def on_ws_disconnected(self):
|
||||||
|
if self.stacked_widget.currentIndex() == 1:
|
||||||
|
self.room_code_display.setText(f"Room: {self.room_code} (Reconnecting...)")
|
||||||
|
self.on_system_message("⚠️ Connection lost. Trying to reconnect...")
|
||||||
|
|
||||||
def on_room_error(self, msg: str):
|
def on_room_error(self, msg: str):
|
||||||
QMessageBox.critical(self, "Room Error", msg)
|
QMessageBox.critical(self, "Room Error", msg)
|
||||||
@@ -537,6 +551,19 @@ class VlcSyncApp(QMainWindow):
|
|||||||
for chat in chat_history:
|
for chat in chat_history:
|
||||||
self.on_chat_message(chat.get("username", "Unknown"), chat.get("message", ""), chat.get("timestamp", 0))
|
self.on_chat_message(chat.get("username", "Unknown"), chat.get("message", ""), chat.get("timestamp", 0))
|
||||||
|
|
||||||
|
def on_room_rejoined(self, msg: dict):
|
||||||
|
self.room_code_display.setText(f"Room: {self.room_code}")
|
||||||
|
self.on_system_message("✅ Reconnected to the room.")
|
||||||
|
|
||||||
|
users = msg.get("users", [])
|
||||||
|
if users:
|
||||||
|
self.on_users_updated(users)
|
||||||
|
|
||||||
|
state = msg.get("state", {})
|
||||||
|
if state:
|
||||||
|
# Don't reload media, just resync playback state
|
||||||
|
self.on_sync_event(state)
|
||||||
|
|
||||||
def on_chat_message(self, author: str, text: str, timestamp: int):
|
def on_chat_message(self, author: str, text: str, timestamp: int):
|
||||||
try:
|
try:
|
||||||
dt = datetime.datetime.fromtimestamp(timestamp / 1000.0)
|
dt = datetime.datetime.fromtimestamp(timestamp / 1000.0)
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ class SyncClientThread(QThread):
|
|||||||
connected = pyqtSignal()
|
connected = pyqtSignal()
|
||||||
disconnected = pyqtSignal()
|
disconnected = pyqtSignal()
|
||||||
room_joined = pyqtSignal(dict)
|
room_joined = pyqtSignal(dict)
|
||||||
|
room_rejoined = pyqtSignal(dict)
|
||||||
room_error = pyqtSignal(str)
|
room_error = pyqtSignal(str)
|
||||||
file_check_needed = pyqtSignal(dict) # msg
|
file_check_needed = pyqtSignal(dict) # msg
|
||||||
users_updated = pyqtSignal(list)
|
users_updated = pyqtSignal(list)
|
||||||
@@ -72,9 +73,12 @@ class SyncClientThread(QThread):
|
|||||||
if t == "room_created":
|
if t == "room_created":
|
||||||
self.room_joined.emit(msg)
|
self.room_joined.emit(msg)
|
||||||
|
|
||||||
elif t == "room_joined" or t == "room_rejoined":
|
elif t == "room_joined":
|
||||||
self.room_joined.emit(msg)
|
self.room_joined.emit(msg)
|
||||||
|
|
||||||
|
elif t == "room_rejoined":
|
||||||
|
self.room_rejoined.emit(msg)
|
||||||
|
|
||||||
elif t == "error":
|
elif t == "error":
|
||||||
self.room_error.emit(msg.get("message", "Unknown error"))
|
self.room_error.emit(msg.get("message", "Unknown error"))
|
||||||
|
|
||||||
|
|||||||
@@ -407,9 +407,9 @@ const server = Bun.serve<WSData>({
|
|||||||
const room = rooms.get(roomCode);
|
const room = rooms.get(roomCode);
|
||||||
if (!room) return;
|
if (!room) return;
|
||||||
|
|
||||||
// Don't remove immediately — give a 30s grace period for reconnection
|
// Don't remove immediately — give a 90s grace period for reconnection
|
||||||
const disconnectKey = `${roomCode}:${username}`;
|
const disconnectKey = `${roomCode}:${username}`;
|
||||||
console.log(`[Room ${roomCode}] ${username} disconnected (waiting 30s for reconnect)`);
|
console.log(`[Room ${roomCode}] ${username} disconnected (waiting 90s for reconnect)`);
|
||||||
|
|
||||||
const timer = setTimeout(() => {
|
const timer = setTimeout(() => {
|
||||||
pendingDisconnects.delete(disconnectKey);
|
pendingDisconnects.delete(disconnectKey);
|
||||||
@@ -433,7 +433,7 @@ const server = Bun.serve<WSData>({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 30_000);
|
}, 90_000);
|
||||||
|
|
||||||
pendingDisconnects.set(disconnectKey, timer);
|
pendingDisconnects.set(disconnectKey, timer);
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user