-
Notifications
You must be signed in to change notification settings - Fork 2
/
websocket_handler.go
120 lines (101 loc) · 2.77 KB
/
websocket_handler.go
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package main
import (
"log"
"net/http"
"time"
"github.com/gorilla/websocket"
)
func upgradeWebSocketConnection(w http.ResponseWriter, r *http.Request) (*websocket.Conn, error) {
// upgrader.CheckOrigin = func(r *http.Request) bool {
// return true
// }
socket, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Printf("Connection upgrade failed: %v", err)
http.Error(w, "Connection upgrade failed", http.StatusInternalServerError)
return nil, err
}
sockets = append(sockets, socket)
return socket, nil
}
func SocketHandler(w http.ResponseWriter, r *http.Request) {
socket, err := upgradeWebSocketConnection(w, r)
if err != nil {
return
}
RoomMatching(socket)
}
func SpectatorHandler(w http.ResponseWriter, r *http.Request) {
socket, err := upgradeWebSocketConnection(w, r)
if err != nil {
return
}
BroadcastConnectionsCount()
for {
roomWithUser2Exists := false
for _, room := range rooms {
if room.user2.check {
message := SpectatorMessage{room.board_15x15, nil, nil, room.user1.nickname, room.user2.nickname}
if err := socket.WriteJSON(message); err != nil {
log.Printf("Error writing to WebSocket: %v", err)
handleSocketError(socket)
return
}
room.spectators = append(room.spectators, socket)
_, _, err := socket.ReadMessage()
if err != nil {
log.Printf("Error reading from WebSocket: %v", err)
handleSocketError(socket)
return
}
removeSocketFromSpectators(room, socket)
roomWithUser2Exists = true
}
}
if !roomWithUser2Exists {
if IsWebSocketConnected(socket) {
time.Sleep(5 * time.Second)
} else {
handleSocketError(socket)
return
}
}
}
}
func IsWebSocketConnected(conn *websocket.Conn) bool {
log.Println("Checking WebSocket connection...")
if err := conn.WriteJSON(map[string]interface{}{"type": WebSocketPingType}); err != nil {
log.Printf("Failed to send Ping message: %v", err)
return false
}
if err := conn.SetReadDeadline(time.Now().Add(5 * time.Second)); err != nil {
log.Printf("Failed to set Read deadline: %v", err)
return false
}
defer conn.SetReadDeadline(time.Time{})
if _, pong, err := conn.ReadMessage(); err != nil || string(pong) != WebSocketPongType {
log.Printf("Failed to receive Pong message: %v", err)
return false
}
return true
}
func handleSocketError(socket *websocket.Conn) {
removeWebSocketFromSockets(socket)
socket.Close()
}
func removeSocketFromSpectators(room *OmokRoom, socket *websocket.Conn) {
for i, r := range room.spectators {
if r == socket {
room.spectators = append(room.spectators[:i], room.spectators[i+1:]...)
break
}
}
}
func removeWebSocketFromSockets(socket *websocket.Conn) {
for i, r := range sockets {
if r == socket {
sockets = append(sockets[:i], sockets[i+1:]...)
break
}
}
}