Skip to content

Commit 95c92f9

Browse files
committed
Store text-editor content within server
This allows data to be filled in upon reconnection However, this requires removal of the dmp. TODO: Check if getting rid of dmp worsens performance
1 parent c4a2387 commit 95c92f9

File tree

4 files changed

+186
-113
lines changed

4 files changed

+186
-113
lines changed

collab/main.go

Lines changed: 92 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package main
22

33
import (
4-
verify "collab/verify"
4+
"collab/verify"
55
"context"
66
"encoding/json"
77
"io"
@@ -15,6 +15,15 @@ import (
1515
"github.com/gorilla/websocket"
1616
)
1717

18+
// types
19+
const (
20+
AUTH = "auth"
21+
AUTH_SUCCESS = "auth_success"
22+
AUTH_FAIL = "auth_fail"
23+
CLOSE_SESSION = "close_session"
24+
CONTENT_CHANGE = "content_change"
25+
)
26+
1827
var upgrader = websocket.Upgrader{
1928
CheckOrigin: func(r *http.Request) bool {
2029
return true
@@ -37,10 +46,12 @@ type Hub struct {
3746
}
3847

3948
type Message struct {
40-
Type string `json:"type"`
41-
RoomID string `json:"roomId"`
42-
Content []byte `json:"data"`
43-
UserID string `json:"userId"`
49+
Type string `json:"type"`
50+
RoomID string `json:"roomId"`
51+
Content string `json:"data"`
52+
UserID string `json:"userId"`
53+
Token string `json:"token"`
54+
MatchHash string `json:"matchHash"`
4455
}
4556

4657
func verifyToken(token string) (bool, string) {
@@ -127,10 +138,19 @@ func (h *Hub) Run() {
127138
case message := <-h.broadcast:
128139
h.mutex.Lock()
129140
// Update the current workspace for this RoomID
130-
h.workspaces[message.RoomID] = string(message.Content)
141+
h.workspaces[message.RoomID] = message.Content
131142
for client := range h.clients {
132143
if client.roomID == message.RoomID {
133-
err := client.conn.WriteMessage(websocket.TextMessage, message.Content)
144+
145+
log.Println("Original message: ", message)
146+
147+
msgJson, _ := json.Marshal(message)
148+
149+
log.Printf("Sending message to client: %s", msgJson)
150+
151+
err := client.conn.WriteMessage(websocket.TextMessage,
152+
msgJson,
153+
)
134154
if err != nil {
135155
log.Printf("Error sending message: %v", err)
136156
client.conn.Close()
@@ -140,9 +160,6 @@ func (h *Hub) Run() {
140160
}
141161
h.mutex.Unlock()
142162
}
143-
144-
145-
146163
}
147164
}
148165

@@ -165,7 +182,6 @@ func serveWs(
165182
return
166183
}
167184

168-
169185
client := &Client{conn: conn, roomID: roomID}
170186
hub.register <- client
171187

@@ -214,27 +230,35 @@ func handleMessages(
214230
break
215231
}
216232

217-
var msgData map[string]interface{}
233+
log.Printf("Raw message received: %s", string(message))
234+
235+
var msgData Message
218236
if err := json.Unmarshal(message, &msgData); err != nil {
219237
log.Printf("Failed to parse message: %v", err)
220238
continue
221239
}
222240

241+
log.Printf("Raw message parsed: %s", msgData)
223242

224-
if msgData["type"] == "auth" {
225-
token, tokenOk := msgData["token"].(string)
226-
if !tokenOk {
243+
if msgData.Type == AUTH {
244+
token := msgData.Token
245+
if token == "" {
227246
log.Println("Authentication failed - no token attached")
228-
client.conn.WriteMessage(
229-
websocket.TextMessage,
230-
[]byte("Authentication failed"),
231-
)
247+
248+
msg := Message{
249+
Type: AUTH_FAIL,
250+
RoomID: client.roomID,
251+
Content: "Authentication failed - no token attached",
252+
}
253+
msgJson, _ := json.Marshal(msg)
254+
client.conn.WriteMessage(websocket.TextMessage, msgJson)
232255
client.conn.Close()
233256
break
234257
}
235258
isSuccess := false
236-
match, matchOk := msgData["matchHash"].(string)
237-
if matchOk && !authenticateClient(token, match, client, roomMappings, persistMappings) {
259+
match := msgData.MatchHash
260+
if match != "" &&
261+
!authenticateClient(token, match, client, roomMappings, persistMappings) {
238262
log.Println(
239263
"failed to find a matching room from match hash, proceeding with persistence check",
240264
)
@@ -247,70 +271,91 @@ func handleMessages(
247271
isSuccess = true
248272
}
249273
if !isSuccess {
250-
client.conn.WriteMessage(
251-
websocket.TextMessage,
252-
[]byte("Authentication failed"),
253-
)
274+
msg := Message{
275+
Type: AUTH_FAIL,
276+
RoomID: client.roomID,
277+
Content: "Authentication failed",
278+
}
279+
msgJson, _ := json.Marshal(msg)
280+
client.conn.WriteMessage(websocket.TextMessage, msgJson)
281+
254282
client.conn.Close()
255283
break
256284
}
257285
client.authenticated = true
258-
client.conn.WriteMessage(
259-
websocket.TextMessage,
260-
[]byte("Auth Success"),
261-
)
262-
log.Println("Client authenticated successfully")
263-
}
264286

265-
if msgData["type"] == "close_session" {
287+
serverContent := hub.workspaces[client.roomID]
288+
289+
newMsg := Message{
290+
Type: AUTH_SUCCESS,
291+
RoomID: client.roomID,
292+
Content: serverContent,
293+
}
294+
msgJson, _ := json.Marshal(newMsg)
295+
client.conn.WriteMessage(websocket.TextMessage, msgJson)
296+
297+
log.Println("Client authenticated successfully")
298+
} else if msgData.Type == CLOSE_SESSION {
266299
closeMessage := Message{
267300
RoomID: client.roomID,
268-
Content: []byte("The session has been closed by a user."),
301+
Content: "The session has been closed by a user.",
269302
}
270-
targetId := msgData["userId"].(string)
303+
targetId := msgData.UserID
271304
data, err := persistMappings.Conn.HGetAll(context.Background(), targetId).Result()
272305
if err != nil {
273306
log.Printf("Error retrieving data for userID %s: %v", targetId, err)
274307
} else {
275308
_, err1 := persistMappings.Conn.Del(context.Background(), targetId).Result()
276309
if err1 != nil {
277-
log.Printf("Error deleting data for userID %s: %v", targetId, err1);
310+
log.Printf("Error deleting data for userID %s: %v", targetId, err1)
278311
}
279312
_, err2 := persistMappings.Conn.Del(context.Background(), data["otherUser"]).Result()
280313
if err2 != nil {
281-
log.Printf("Error deleting data for other user %s: %v", data["otherUser"], err2);
314+
log.Printf("Error deleting data for other user %s: %v", data["otherUser"], err2)
282315
}
283316
}
284317
hub.broadcast <- closeMessage
318+
} else if msgData.Type == CONTENT_CHANGE {
319+
// Broadcast the message to other clients
320+
hub.broadcast <- Message{
321+
RoomID: client.roomID,
322+
Content: msgData.Content,
323+
Type: msgData.Type,
324+
UserID: msgData.UserID,
325+
}
326+
} else {
327+
log.Printf("Unknown message type: %s", msgData.Type)
285328
}
286-
287-
// Broadcast the message to other clients
288-
userID, _ := msgData["userId"].(string)
289-
hub.broadcast <- Message{RoomID: client.roomID, Content: message, UserID: userID}
290329
}
291330
}
292331

332+
type ClientWorkspace struct {
333+
Clients int `json:"clients"`
334+
Workspace string `json:"workspace"`
335+
}
336+
293337
// Status endpoint that shows the number of clients and the current color for each roomID
294338
func statusHandler(hub *Hub) gin.HandlerFunc {
339+
295340
return func(c *gin.Context) {
296341
hub.mutex.Lock()
297342
defer hub.mutex.Unlock()
298343

299-
status := make(map[string]interface{})
344+
status := make(map[string]ClientWorkspace)
300345
for client := range hub.clients {
301346
roomID := client.roomID
302347
currentStatus, ok := status[roomID]
303348
if !ok {
304349
// Initialize status for a new roomID
305-
status[roomID] = map[string]interface{}{
306-
"clients": 1,
307-
"workspace": hub.workspaces[roomID],
350+
status[roomID] = ClientWorkspace{
351+
Clients: 1,
352+
Workspace: hub.workspaces[roomID],
308353
}
309354
} else {
310355
// Update the client count for an existing roomID
311-
status[roomID] = map[string]interface{}{
312-
"clients": currentStatus.(map[string]interface{})["clients"].(int) + 1,
313-
"workspace": hub.workspaces[roomID],
356+
status[roomID] = ClientWorkspace{
357+
Clients: currentStatus.Clients + 1,
358+
Workspace: hub.workspaces[roomID],
314359
}
315360
}
316361
}

peerprep/app/questions/[question]/[roomID]/question.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ interface Props {
1212
authToken?: string;
1313
userId?: string;
1414
matchHash?: string;
15-
1615
}
1716

1817
interface DifficultyChipProps {
@@ -29,7 +28,13 @@ function DifficultyChip({ diff }: DifficultyChipProps) {
2928
);
3029
}
3130

32-
function QuestionBlock({ question, roomID, authToken, userId, matchHash }: Props) {
31+
function QuestionBlock({
32+
question,
33+
roomID,
34+
authToken,
35+
userId,
36+
matchHash,
37+
}: Props) {
3338
return (
3439
<>
3540
<div className={styles.qn_container}>
@@ -64,7 +69,6 @@ function QuestionBlock({ question, roomID, authToken, userId, matchHash }: Props
6469
</div>
6570
<div className={styles.editor_container}>
6671
<CollabEditor
67-
question={question}
6872
roomID={roomID}
6973
authToken={authToken}
7074
matchHash={matchHash}

peerprep/app/questions/[question]/question.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ function QuestionBlock({ question }: Props) {
8484
}
8585
</div>
8686
<div className={styles.editor_container}>
87-
<CollabEditor question={question} />
87+
<CollabEditor />
8888
</div>
8989
</>
9090
);

0 commit comments

Comments
 (0)