-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathhandle_websocket.go
More file actions
93 lines (79 loc) · 1.88 KB
/
handle_websocket.go
File metadata and controls
93 lines (79 loc) · 1.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package main
import (
"encoding/json"
"flashmeet/middleware"
"flashmeet/redis"
"log"
"net/http"
"sync"
"time"
"github.com/google/uuid"
"github.com/gorilla/websocket"
)
var clients = make(map[string]*Client)
var clientsMu sync.RWMutex
const maxConns = 50000
func handleWebSocket(w http.ResponseWriter, r *http.Request) {
clientsMu.RLock()
count := len(clients)
clientsMu.RUnlock()
if count >= maxConns {
http.Error(w, "Server at capacity", http.StatusServiceUnavailable)
return
}
if !middleware.EnsureUpgradeChecks(w, r) {
return
}
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println("upgrade error:", err)
return
}
conn.SetReadDeadline(time.Now().Add(60 * time.Second))
conn.SetPongHandler(func(string) error {
conn.SetReadDeadline(time.Now().Add(60 * time.Second))
return nil
})
defer conn.Close()
log.Println("client connected:", conn.RemoteAddr())
client := &Client{
ID: uuid.NewString(),
Conn: conn,
Send: make(chan SendMessageType, 256),
done: make(chan struct{}),
}
clientsMu.Lock()
clients[client.ID] = client
clientsMu.Unlock()
ip := r.RemoteAddr
err = redis.RegisterClient(client.ID, ip, serverID)
defer func() {
clientsMu.Lock()
delete(clients, client.ID)
clientsMu.Unlock()
redis.Client.Del(redis.Ctx, "client:"+client.ID)
}()
if err != nil {
log.Println("failed to register client in redis:", err)
return
}
go client.writePump()
go client.readPump()
go client.keepAlive(serverID)
welcomeMsg := map[string]any{
"message": "Hello from server",
"timestamp": time.Now().Unix(),
}
msgBytes, err := json.Marshal(welcomeMsg)
if err != nil {
log.Println("json marshal error:", err)
return
}
client.Send <- SendMessageType{
Message: msgBytes,
Type: websocket.TextMessage,
}
<-client.done
redis.Client.Del(redis.Ctx, "client:"+client.ID)
log.Println("handleWebSocket exiting for:", client.ID)
}