1
1
package main
2
2
3
3
import (
4
- verify "collab/verify"
4
+ "collab/verify"
5
5
"context"
6
6
"encoding/json"
7
7
"io"
@@ -10,11 +10,22 @@ import (
10
10
"os"
11
11
"strconv"
12
12
"sync"
13
+ "time"
13
14
14
15
"github.com/gin-gonic/gin"
15
16
"github.com/gorilla/websocket"
16
17
)
17
18
19
+ // types
20
+ const (
21
+ AUTH = "auth"
22
+ AUTH_SUCCESS = "auth_success"
23
+ AUTH_FAIL = "auth_fail"
24
+ CLOSE_SESSION = "close_session"
25
+ CONTENT_CHANGE = "content_change"
26
+ PING = "ping"
27
+ )
28
+
18
29
var upgrader = websocket.Upgrader {
19
30
CheckOrigin : func (r * http.Request ) bool {
20
31
return true
@@ -37,10 +48,12 @@ type Hub struct {
37
48
}
38
49
39
50
type Message struct {
40
- Type string `json:"type"`
41
- RoomID string `json:"roomId"`
42
- Content []byte `json:"data"`
43
- UserID string `json:"userId"`
51
+ Type string `json:"type"`
52
+ RoomID string `json:"roomId"`
53
+ Content string `json:"data"`
54
+ UserID string `json:"userId"`
55
+ Token string `json:"token"`
56
+ MatchHash string `json:"matchHash"`
44
57
}
45
58
46
59
func verifyToken (token string ) (bool , string ) {
@@ -127,10 +140,19 @@ func (h *Hub) Run() {
127
140
case message := <- h .broadcast :
128
141
h .mutex .Lock ()
129
142
// Update the current workspace for this RoomID
130
- h .workspaces [message .RoomID ] = string ( message .Content )
143
+ h .workspaces [message .RoomID ] = message .Content
131
144
for client := range h .clients {
132
145
if client .roomID == message .RoomID {
133
- err := client .conn .WriteMessage (websocket .TextMessage , message .Content )
146
+
147
+ log .Println ("Original message: " , message )
148
+
149
+ msgJson , _ := json .Marshal (message )
150
+
151
+ log .Printf ("Sending message to client: %s" , msgJson )
152
+
153
+ err := client .conn .WriteMessage (websocket .TextMessage ,
154
+ msgJson ,
155
+ )
134
156
if err != nil {
135
157
log .Printf ("Error sending message: %v" , err )
136
158
client .conn .Close ()
@@ -142,7 +164,7 @@ func (h *Hub) Run() {
142
164
}
143
165
144
166
145
-
167
+
146
168
}
147
169
}
148
170
@@ -165,7 +187,6 @@ func serveWs(
165
187
return
166
188
}
167
189
168
-
169
190
client := & Client {conn : conn , roomID : roomID }
170
191
hub .register <- client
171
192
@@ -214,27 +235,35 @@ func handleMessages(
214
235
break
215
236
}
216
237
217
- var msgData map [string ]interface {}
238
+ log .Printf ("Raw message received: %s" , string (message ))
239
+
240
+ var msgData Message
218
241
if err := json .Unmarshal (message , & msgData ); err != nil {
219
242
log .Printf ("Failed to parse message: %v" , err )
220
243
continue
221
244
}
222
245
246
+ log .Printf ("Raw message parsed: %s" , msgData )
223
247
224
- if msgData [ "type" ] == "auth" {
225
- token , tokenOk := msgData [ "token" ].( string )
226
- if ! tokenOk {
248
+ if msgData . Type == AUTH {
249
+ token := msgData . Token
250
+ if token == "" {
227
251
log .Println ("Authentication failed - no token attached" )
228
- client .conn .WriteMessage (
229
- websocket .TextMessage ,
230
- []byte ("Authentication failed" ),
231
- )
252
+
253
+ msg := Message {
254
+ Type : AUTH_FAIL ,
255
+ RoomID : client .roomID ,
256
+ Content : "Authentication failed - no token attached" ,
257
+ }
258
+ msgJson , _ := json .Marshal (msg )
259
+ client .conn .WriteMessage (websocket .TextMessage , msgJson )
232
260
client .conn .Close ()
233
261
break
234
262
}
235
263
isSuccess := false
236
- match , matchOk := msgData ["matchHash" ].(string )
237
- if matchOk && ! authenticateClient (token , match , client , roomMappings , persistMappings ) {
264
+ match := msgData .MatchHash
265
+ if match != "" &&
266
+ ! authenticateClient (token , match , client , roomMappings , persistMappings ) {
238
267
log .Println (
239
268
"failed to find a matching room from match hash, proceeding with persistence check" ,
240
269
)
@@ -247,70 +276,130 @@ func handleMessages(
247
276
isSuccess = true
248
277
}
249
278
if ! isSuccess {
250
- client .conn .WriteMessage (
251
- websocket .TextMessage ,
252
- []byte ("Authentication failed" ),
253
- )
279
+ msg := Message {
280
+ Type : AUTH_FAIL ,
281
+ RoomID : client .roomID ,
282
+ Content : "Authentication failed" ,
283
+ }
284
+ msgJson , _ := json .Marshal (msg )
285
+ client .conn .WriteMessage (websocket .TextMessage , msgJson )
286
+
254
287
client .conn .Close ()
255
288
break
256
289
}
257
290
client .authenticated = true
258
- client .conn .WriteMessage (
259
- websocket .TextMessage ,
260
- []byte ("Auth Success" ),
261
- )
291
+
292
+ serverContent := hub .workspaces [client .roomID ]
293
+
294
+ newMsg := Message {
295
+ Type : AUTH_SUCCESS ,
296
+ RoomID : client .roomID ,
297
+ Content : serverContent ,
298
+ }
299
+ msgJson , _ := json .Marshal (newMsg )
300
+ client .conn .WriteMessage (websocket .TextMessage , msgJson )
301
+
262
302
log .Println ("Client authenticated successfully" )
263
303
}
264
304
265
- if msgData ["type" ] == "close_session" {
305
+ // old logic before type changes
306
+ // if msgData["type"] == "ping" {
307
+ // //receives ping from client1, need to send a ping to client2
308
+ // //eventually, if present, client2 will send the ping back, which will be broadcasted back to client1.
309
+
310
+ // userID, _ := msgData["userId"].(string)
311
+ // request := Message {
312
+ // RoomID: client.roomID,
313
+ // UserID: userID,
314
+ // Content: []byte("ping request"),
315
+ // }
316
+
317
+ // hub.broadcast <- request
318
+ // }
319
+
320
+ if msgData .Type == CLOSE_SESSION {
266
321
closeMessage := Message {
267
322
RoomID : client .roomID ,
268
- Content : [] byte ( "The session has been closed by a user." ) ,
323
+ Content : "The session has been closed by a user." ,
269
324
}
270
- targetId := msgData [ "userId" ].( string )
325
+ targetId := msgData . UserID
271
326
data , err := persistMappings .Conn .HGetAll (context .Background (), targetId ).Result ()
272
327
if err != nil {
273
328
log .Printf ("Error retrieving data for userID %s: %v" , targetId , err )
274
329
} else {
275
330
_ , err1 := persistMappings .Conn .Del (context .Background (), targetId ).Result ()
276
331
if err1 != nil {
277
- log .Printf ("Error deleting data for userID %s: %v" , targetId , err1 );
332
+ log .Printf ("Error deleting data for userID %s: %v" , targetId , err1 )
278
333
}
279
334
_ , err2 := persistMappings .Conn .Del (context .Background (), data ["otherUser" ]).Result ()
280
335
if err2 != nil {
281
- log .Printf ("Error deleting data for other user %s: %v" , data ["otherUser" ], err2 );
336
+ log .Printf ("Error deleting data for other user %s: %v" , data ["otherUser" ], err2 )
282
337
}
283
338
}
284
339
hub .broadcast <- closeMessage
285
- }
340
+ } else if msgData .Type == CONTENT_CHANGE {
341
+ // Broadcast the message to other clients
342
+ hub .broadcast <- Message {
343
+ RoomID : client .roomID ,
344
+ Content : msgData .Content ,
345
+ Type : msgData .Type ,
346
+ UserID : msgData .UserID ,
347
+ }
348
+ } else if msgData .Type == PING {
349
+ // Broadcast the message to other clients
350
+ hub .broadcast <- Message {
351
+ RoomID : client .roomID ,
352
+ Type : msgData .Type ,
353
+ UserID : msgData .UserID ,
354
+ }
286
355
287
- // Broadcast the message to other clients
288
- userID , _ := msgData ["userId" ].(string )
289
- hub .broadcast <- Message {RoomID : client .roomID , Content : message , UserID : userID }
356
+ extendExpiryTime (msgData .UserID , persistMappings )
357
+ } else {
358
+ log .Printf ("Unknown message type: %s" , msgData .Type )
359
+ }
290
360
}
291
361
}
292
362
363
+ func extendExpiryTime (userId string , persistMappings * verify.PersistMappings ) {
364
+
365
+ ctx := context .Background ()
366
+ if err := persistMappings .Conn .Expire (ctx , userId , time .Minute * 10 ).Err (); err != nil {
367
+ log .Println ("Error extending room time on ping: " , err .Error ())
368
+ } else {
369
+
370
+ log .Printf ("expiration reset for 10 minutes for user %s: " , userId )
371
+ }
372
+
373
+
374
+ }
375
+
376
+ type ClientWorkspace struct {
377
+ Clients int `json:"clients"`
378
+ Workspace string `json:"workspace"`
379
+ }
380
+
293
381
// Status endpoint that shows the number of clients and the current color for each roomID
294
382
func statusHandler (hub * Hub ) gin.HandlerFunc {
383
+
295
384
return func (c * gin.Context ) {
296
385
hub .mutex .Lock ()
297
386
defer hub .mutex .Unlock ()
298
387
299
- status := make (map [string ]interface {} )
388
+ status := make (map [string ]ClientWorkspace )
300
389
for client := range hub .clients {
301
390
roomID := client .roomID
302
391
currentStatus , ok := status [roomID ]
303
392
if ! ok {
304
393
// Initialize status for a new roomID
305
- status [roomID ] = map [ string ] interface {} {
306
- "clients" : 1 ,
307
- "workspace" : hub .workspaces [roomID ],
394
+ status [roomID ] = ClientWorkspace {
395
+ Clients : 1 ,
396
+ Workspace : hub .workspaces [roomID ],
308
397
}
309
398
} else {
310
399
// 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 ],
400
+ status [roomID ] = ClientWorkspace {
401
+ Clients : currentStatus .Clients + 1 ,
402
+ Workspace : hub .workspaces [roomID ],
314
403
}
315
404
}
316
405
}
0 commit comments