Skip to content

Commit 21edd4c

Browse files
committed
Fix multiple cconnection bug
1 parent 46bf07e commit 21edd4c

File tree

1 file changed

+45
-69
lines changed

1 file changed

+45
-69
lines changed
Lines changed: 45 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useEffect, useState } from 'react';
1+
import React, { useEffect, useState, useRef } from 'react';
22
import { useParams, useNavigate } from 'react-router-dom';
33
import * as Y from 'yjs';
44
import { WebsocketProvider } from 'y-websocket';
@@ -16,32 +16,27 @@ import Spinner from 'react-bootstrap/Spinner';
1616
const CollaborationSpace = () => {
1717
const navigate = useNavigate();
1818
const { roomId } = useParams(); // Get the roomId from the URL
19+
const websocketRef = useRef(null); // Use ref to persist websocket across renders
1920
const [yDoc, setYDoc] = useState(null);
2021
const [provider, setProvider] = useState(null);
21-
const [websocket, setWebsocket] = useState(null); // add websocket state to be access by other functions
2222
const [code, setCode] = useState('');
23-
const [users, setUsers] = useState([]); // track users in the room
24-
const [userId, setUserId] = useState(""); // current user
25-
const [language, setLanguage] = useState("python") // set default language to python
26-
const [output, setOutput] = useState("")
27-
23+
const [users, setUsers] = useState([]); // Track users in the room
24+
const [userId, setUserId] = useState(""); // Current user
25+
const [language, setLanguage] = useState("python"); // Set default language to python
26+
const [output, setOutput] = useState("");
27+
2828
const LANGUAGEVERSIONS = {
2929
"python" : "3.10.0",
3030
"java" : "15.0.2",
3131
"c++": "10.2.0"
3232
};
3333

34-
const [showAccessDeniedToast, setShowAccessDeniedToast] = useState(
35-
JSON.parse(sessionStorage.getItem('showAccessDeniedToast')) || false
36-
);
34+
const [showAccessDeniedToast, setShowAccessDeniedToast] = useState(false);
3735
const [toastMessage, setToastMessage] = useState('');
38-
const [loading, setLoading] = useState(
39-
JSON.parse(sessionStorage.getItem('loading')) !== false
40-
);
36+
const [loading, setLoading] = useState(true);
4137

4238
const handleCloseToast = () => {
4339
setShowAccessDeniedToast(false);
44-
sessionStorage.setItem('showAccessDeniedToast', false);
4540
navigate("/home");
4641
};
4742

@@ -58,74 +53,61 @@ const CollaborationSpace = () => {
5853
};
5954

6055
fetchUser();
61-
// Sync states with sessionStorage
56+
6257
return () => {
63-
sessionStorage.setItem('loading', loading);
64-
sessionStorage.setItem('showAccessDeniedToast', showAccessDeniedToast);
58+
if (websocketRef.current) {
59+
websocketRef.current.close();
60+
websocketRef.current = null;
61+
}
62+
if (provider) provider.destroy();
63+
if (yDoc) yDoc.destroy();
6564
};
66-
}, [loading, showAccessDeniedToast]);
65+
}, []);
6766

6867
const initiateWebSocket = (userId) => {
68+
if (websocketRef.current) return; // Prevent duplicate connections
6969
const websocket = new WebSocket("ws://localhost:3004");
70-
setWebsocket(websocket);
70+
websocketRef.current = websocket;
7171

7272
websocket.onopen = () => {
73-
websocket.send(JSON.stringify( {type: 'joinRoom', roomId, userId: userId}));
74-
75-
// Request userIds when matched user rejoins
73+
websocket.send(JSON.stringify({ type: 'joinRoom', roomId, userId }));
7674
websocket.send(JSON.stringify({ type: 'requestUserList', roomId }));
7775
};
7876

7977
websocket.onmessage = (event) => {
8078
const data = JSON.parse(event.data);
81-
const stringData = JSON.stringify(data);
82-
console.log(`[FRONTEND] data message is ${stringData}`);
79+
console.log(`[FRONTEND] data message is ${JSON.stringify(data)}`);
8380
switch (data.type) {
8481
case 'usersListUpdate':
85-
setUsers(data.users); // Update the user list
82+
setUsers(data.users); // Update the user list
8683
setShowAccessDeniedToast(false);
87-
setLoading(false); // Access allowed; stop loading
88-
sessionStorage.setItem('loading', false);
84+
setLoading(false); // Access allowed; stop loading
8985
break;
9086
case 'accessDenied':
9187
setToastMessage(data.message);
9288
setShowAccessDeniedToast(true);
9389
setLoading(false);
94-
sessionStorage.setItem('showAccessDeniedToast', true);
9590
break;
9691
default:
9792
console.log("No messages received from room management server");
9893
break;
9994
}
10095
};
10196

102-
// create a Yjs document for collaboration
10397
const doc = new Y.Doc();
10498
setYDoc(doc);
10599

106-
// create websocket provider to synchronize the document
107100
const wsProvider = new WebsocketProvider("ws://localhost:1234", roomId, doc);
108101
setProvider(wsProvider);
109102

110-
// Create a shared type in Yjs for collaborative code editing
111103
const yText = doc.getText('monacoEditor');
112-
113-
// Update monaco editor with Yjs changes
114104
yText.observe(() => {
115105
setCode(yText.toString());
116106
});
117-
118-
return () => {
119-
// clean up for room management
120-
wsProvider.destroy();
121-
doc.destroy();
122-
};
123107
};
124108

125109
const handleExit = () => {
126-
websocket.send(JSON.stringify({ type: 'leaveRoom', roomId, userId}));
127-
if (provider) provider.destroy();
128-
if (yDoc) yDoc.destroy();
110+
if (websocketRef.current) websocketRef.current.send(JSON.stringify({ type: 'leaveRoom', roomId, userId }));
129111
navigate("/home");
130112
};
131113

@@ -137,8 +119,8 @@ const CollaborationSpace = () => {
137119
};
138120

139121
collabService.getCodeOutput(code_message)
140-
.then(result => setOutput(result.data.run.output))
141-
.catch(err => console.log(err));
122+
.then(result => setOutput(result.data.run.output))
123+
.catch(err => console.log(err));
142124
};
143125

144126
const handleEditorChange = (value) => {
@@ -149,7 +131,7 @@ const CollaborationSpace = () => {
149131

150132
if (loading) {
151133
return (
152-
<div style={{ textAlign: 'center', marginTop: '50px' }}>
134+
<div style={{ textAlign: 'center' }}>
153135
<Spinner animation="border" variant="primary" role="status">
154136
<span className="visually-hidden">Loading...</span>
155137
</Spinner>
@@ -161,26 +143,21 @@ const CollaborationSpace = () => {
161143
return (
162144
<div style={{ textAlign: 'center' }}>
163145
{showAccessDeniedToast ? (
164-
<ToastContainer
165-
className="p-3"
166-
position="top-center"
167-
style={{ zIndex: 1 }}
168-
>
169-
<Toast
170-
onClose={handleCloseToast}
171-
show={showAccessDeniedToast}
172-
delay={3000}
173-
autohide
174-
bg="danger"
175-
>
176-
<Toast.Body className='text-white'>
177-
<strong>{toastMessage}</strong>
178-
</Toast.Body>
179-
</Toast>
180-
</ToastContainer>
181-
) : (
182-
<>
183-
<div>
146+
<ToastContainer className="p-3" position="top-center" style={{ zIndex: 1 }}>
147+
<Toast
148+
onClose={handleCloseToast}
149+
show={showAccessDeniedToast}
150+
delay={3000}
151+
autohide
152+
bg="danger"
153+
>
154+
<Toast.Body className='text-white'>
155+
<strong>{toastMessage}</strong>
156+
</Toast.Body>
157+
</Toast>
158+
</ToastContainer>
159+
) : (
160+
<>
184161
<CollabNavigationBar handleExit={handleExit} handleCodeRun={handleCodeRun} users={users} setLanguage={setLanguage} language={language}/>
185162
<Container fluid style={{ marginTop: '20px' }}>
186163
<Row>
@@ -193,11 +170,10 @@ const CollaborationSpace = () => {
193170
</Col>
194171
</Row>
195172
</Container>
196-
</div>
197-
</>
198-
)}
173+
</>
174+
)}
199175
</div>
200176
);
201177
};
202178

203-
export default CollaborationSpace;
179+
export default CollaborationSpace;

0 commit comments

Comments
 (0)