Skip to content

Commit d7aaa90

Browse files
committed
Handle collab end on client refresh
1 parent 683f032 commit d7aaa90

File tree

8 files changed

+99
-87
lines changed

8 files changed

+99
-87
lines changed

backend/collab-service/src/handlers/websocketHandler.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ export const handleWebsocketCollabEvents = (socket: Socket) => {
3737
const connectionKey = `${uid}:${roomId}`;
3838
if (userConnections.has(connectionKey)) {
3939
clearTimeout(userConnections.get(connectionKey)!);
40-
return;
4140
}
4241
userConnections.set(connectionKey, null);
4342

@@ -50,11 +49,10 @@ export const handleWebsocketCollabEvents = (socket: Socket) => {
5049
socket.join(roomId);
5150
socket.data.roomId = roomId;
5251

53-
if (
54-
io.sockets.adapter.rooms.get(roomId)?.size === 2 &&
55-
!collabSessions.has(roomId)
56-
) {
57-
createCollabSession(roomId);
52+
if (io.sockets.adapter.rooms.get(roomId)?.size === 2) {
53+
if (!collabSessions.has(roomId)) {
54+
createCollabSession(roomId);
55+
}
5856
io.to(roomId).emit(CollabEvents.ROOM_READY, true);
5957
}
6058
});

backend/matching-service/src/handlers/websocketHandler.ts

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -119,27 +119,24 @@ export const handleWebsocketMatchEvents = (socket: Socket) => {
119119
userConnections.delete(uid);
120120
});
121121

122-
socket.on(
123-
MatchEvents.MATCH_ACCEPT_REQUEST,
124-
(matchId: string, userId1: string, userId2: string) => {
125-
const partnerAccepted = handleMatchAccept(matchId);
126-
if (partnerAccepted) {
127-
const match = getMatchById(matchId);
128-
if (!match) {
129-
return;
130-
}
131-
132-
const { complexity, category } = match;
133-
getRandomQuestion(complexity, category).then((res) => {
134-
io.to(matchId).emit(
135-
MatchEvents.MATCH_SUCCESSFUL,
136-
res.data.question.id,
137-
res.data.question.title
138-
);
139-
});
122+
socket.on(MatchEvents.MATCH_ACCEPT_REQUEST, (matchId: string) => {
123+
const partnerAccepted = handleMatchAccept(matchId);
124+
if (partnerAccepted) {
125+
const match = getMatchById(matchId);
126+
if (!match) {
127+
return;
140128
}
129+
130+
const { complexity, category } = match;
131+
getRandomQuestion(complexity, category).then((res) => {
132+
io.to(matchId).emit(
133+
MatchEvents.MATCH_SUCCESSFUL,
134+
res.data.question.id,
135+
res.data.question.title
136+
);
137+
});
141138
}
142-
);
139+
});
143140

144141
socket.on(
145142
MatchEvents.MATCH_DECLINE_REQUEST,

frontend/src/components/CodeEditor/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ const CodeEditor: React.FC<CodeEditorProps> = (props) => {
101101
};
102102
loadTemplate();
103103
// eslint-disable-next-line react-hooks/exhaustive-deps
104-
}, [isReadOnly, isEditorReady]);
104+
}, [isReadOnly, isEditorReady, editorState]);
105105

106106
return (
107107
<CodeMirror

frontend/src/contexts/CollabContext.tsx

Lines changed: 70 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
COLLAB_SUBMIT_ERROR,
1717
COLLAB_DOCUMENT_ERROR,
1818
COLLAB_DOCUMENT_RESTORED,
19+
COLLAB_RECONNECTION_ERROR,
1920
} from "../utils/constants";
2021
import { toast } from "react-toastify";
2122

@@ -173,6 +174,7 @@ const CollabProvider: React.FC<{ children?: React.ReactNode }> = (props) => {
173174
const roomId = getMatchId();
174175
if (!matchUser || !roomId || !qnHistoryIdRef.current) {
175176
toast.error(COLLAB_END_ERROR);
177+
appNavigate("/home");
176178
return;
177179
}
178180

@@ -213,8 +215,6 @@ const CollabProvider: React.FC<{ children?: React.ReactNode }> = (props) => {
213215
};
214216

215217
const handleExitSession = () => {
216-
setIsExitSessionModalOpen(false);
217-
218218
// Delete match data
219219
stopMatch();
220220
appNavigate("/home");
@@ -228,31 +228,80 @@ const CollabProvider: React.FC<{ children?: React.ReactNode }> = (props) => {
228228
doc: Doc,
229229
setIsDocumentLoaded: React.Dispatch<React.SetStateAction<boolean>>
230230
) => {
231-
collabSocket.on(CollabEvents.DOCUMENT_READY, (qnHistoryId: string) => {
232-
setQnHistoryId(qnHistoryId);
233-
});
234-
235-
collabSocket.on(CollabEvents.DOCUMENT_NOT_FOUND, () => {
236-
toast.error(COLLAB_DOCUMENT_ERROR);
237-
setIsDocumentLoaded(false);
238-
239-
const text = doc.getText();
240-
doc.transact(() => {
241-
text.delete(0, text.length);
242-
}, matchUser?.id);
243-
244-
collabSocket.once(CollabEvents.UPDATE, (update) => {
245-
applyUpdateV2(doc, new Uint8Array(update), matchUser?.id);
246-
toast.success(COLLAB_DOCUMENT_RESTORED);
247-
setIsDocumentLoaded(true);
231+
if (!collabSocket.hasListeners(CollabEvents.DOCUMENT_READY)) {
232+
collabSocket.on(CollabEvents.DOCUMENT_READY, (qnHistoryId: string) => {
233+
setQnHistoryId(qnHistoryId);
248234
});
235+
}
236+
237+
if (!collabSocket.hasListeners(CollabEvents.DOCUMENT_NOT_FOUND)) {
238+
collabSocket.on(CollabEvents.DOCUMENT_NOT_FOUND, () => {
239+
toast.error(COLLAB_DOCUMENT_ERROR);
240+
setIsDocumentLoaded(false);
241+
242+
const text = doc.getText();
243+
doc.transact(() => {
244+
text.delete(0, text.length);
245+
}, matchUser?.id);
246+
247+
collabSocket.once(CollabEvents.UPDATE, (update) => {
248+
applyUpdateV2(doc, new Uint8Array(update), matchUser?.id);
249+
toast.success(COLLAB_DOCUMENT_RESTORED);
250+
setIsDocumentLoaded(true);
251+
});
252+
253+
collabSocket.emit(CollabEvents.RECONNECT_REQUEST, roomId);
254+
});
255+
}
256+
257+
if (!collabSocket.hasListeners(CollabEvents.SOCKET_DISCONNECT)) {
258+
collabSocket.on(CollabEvents.SOCKET_DISCONNECT, (reason) => {
259+
console.log(reason);
260+
if (
261+
reason !== CollabEvents.SOCKET_CLIENT_DISCONNECT &&
262+
reason !== CollabEvents.SOCKET_SERVER_DISCONNECT
263+
) {
264+
toast.error(COLLAB_DOCUMENT_ERROR);
265+
setIsDocumentLoaded(false);
266+
}
267+
});
268+
}
249269

250-
collabSocket.emit(CollabEvents.RECONNECT_REQUEST, roomId);
251-
});
270+
if (!collabSocket.io.hasListeners(CollabEvents.SOCKET_RECONNECT_SUCCESS)) {
271+
collabSocket.io.on(CollabEvents.SOCKET_RECONNECT_SUCCESS, () => {
272+
const text = doc.getText();
273+
doc.transact(() => {
274+
text.delete(0, text.length);
275+
}, matchUser?.id);
276+
277+
collabSocket.once(CollabEvents.UPDATE, (update) => {
278+
applyUpdateV2(doc, new Uint8Array(update), matchUser?.id);
279+
toast.success(COLLAB_DOCUMENT_RESTORED);
280+
setIsDocumentLoaded(true);
281+
});
282+
283+
collabSocket.emit(CollabEvents.RECONNECT_REQUEST, roomId);
284+
});
285+
}
286+
287+
if (!collabSocket.io.hasListeners(CollabEvents.SOCKET_RECONNECT_FAILED)) {
288+
collabSocket.io.on(CollabEvents.SOCKET_RECONNECT_FAILED, () => {
289+
toast.error(COLLAB_RECONNECTION_ERROR);
290+
291+
if (matchUser) {
292+
leave(matchUser.id, roomId, true);
293+
}
294+
communicationSocket.emit(CommunicationEvents.USER_DISCONNECT);
295+
296+
handleExitSession();
297+
});
298+
}
252299
};
253300

254301
const resetCollab = () => {
255302
setCompilerResult([]);
303+
setIsEndSessionModalOpen(false);
304+
setIsExitSessionModalOpen(false);
256305
setQnHistoryId(null);
257306
};
258307

frontend/src/contexts/MatchContext.tsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -391,12 +391,7 @@ const MatchProvider: React.FC<{ children?: React.ReactNode }> = (props) => {
391391
return;
392392
}
393393

394-
matchSocket.emit(
395-
MatchEvents.MATCH_ACCEPT_REQUEST,
396-
matchId,
397-
matchUser.id,
398-
partner.id
399-
);
394+
matchSocket.emit(MatchEvents.MATCH_ACCEPT_REQUEST, matchId);
400395
};
401396

402397
const rematch = () => {

frontend/src/pages/CollabSandbox/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ const CollabSandbox: React.FC = () => {
5252
resetCollab();
5353

5454
if (!matchUser || !matchId) {
55+
toast.error(COLLAB_CONNECTION_ERROR);
56+
setIsConnecting(false);
5557
return;
5658
}
5759

frontend/src/utils/collabSocket.ts

Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export type CollabSessionData = {
4141
const COLLAB_SOCKET_URL = "http://localhost:3003";
4242

4343
export const collabSocket = io(COLLAB_SOCKET_URL, {
44-
reconnectionAttempts: 3,
44+
reconnectionAttempts: 5,
4545
autoConnect: false,
4646
auth: {
4747
token: getToken(),
@@ -57,7 +57,6 @@ export const join = (
5757
roomId: string
5858
): Promise<CollabSessionData> => {
5959
collabSocket.connect();
60-
initConnectionStatusListeners(roomId);
6160

6261
doc = new Doc();
6362
text = doc.getText();
@@ -141,33 +140,3 @@ export const receiveCursorUpdate = (view: EditorView) => {
141140
});
142141
});
143142
};
144-
145-
export const reconnectRequest = (roomId: string) => {
146-
collabSocket.emit(CollabEvents.RECONNECT_REQUEST, roomId);
147-
};
148-
149-
const initConnectionStatusListeners = (roomId: string) => {
150-
if (!collabSocket.hasListeners(CollabEvents.SOCKET_DISCONNECT)) {
151-
collabSocket.on(CollabEvents.SOCKET_DISCONNECT, (reason) => {
152-
if (
153-
reason !== CollabEvents.SOCKET_CLIENT_DISCONNECT &&
154-
reason !== CollabEvents.SOCKET_SERVER_DISCONNECT
155-
) {
156-
// TODO: Handle socket disconnection
157-
}
158-
});
159-
}
160-
161-
if (!collabSocket.io.hasListeners(CollabEvents.SOCKET_RECONNECT_SUCCESS)) {
162-
collabSocket.io.on(CollabEvents.SOCKET_RECONNECT_SUCCESS, () => {
163-
console.log("reconnect request");
164-
collabSocket.emit(CollabEvents.RECONNECT_REQUEST, roomId);
165-
});
166-
}
167-
168-
if (!collabSocket.io.hasListeners(CollabEvents.SOCKET_RECONNECT_FAILED)) {
169-
collabSocket.io.on(CollabEvents.SOCKET_RECONNECT_FAILED, () => {
170-
console.log("reconnect failed");
171-
});
172-
}
173-
};

frontend/src/utils/constants.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,11 @@ export const COLLAB_ENDED_MESSAGE =
108108
export const COLLAB_PARTNER_DISCONNECTED_MESSAGE =
109109
"Unfortunately, the collaboration session has ended as your partner has disconnected.";
110110
export const COLLAB_CONNECTION_ERROR =
111-
"Error connecting you to the collaboration session! Please try again.";
111+
"Error connecting you to the collaboration session! Please find another match.";
112+
export const COLLAB_RECONNECTION_ERROR =
113+
"Error reconnecting you to the collaboration session! Closing the session...";
112114
export const COLLAB_END_ERROR =
113-
"Error ending the collaboration session! Please try again.";
115+
"Something went wrong! Forcefully ending the session...";
114116
export const COLLAB_SUBMIT_ERROR =
115117
"Error submitting your attempt! Please try again.";
116118
export const COLLAB_DOCUMENT_ERROR =

0 commit comments

Comments
 (0)