-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathmain.go
93 lines (73 loc) · 2.23 KB
/
main.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
package main
import (
"flag"
"log"
"github.com/gofiber/fiber"
"github.com/gofiber/websocket"
)
type client struct{} // Add more data to this type if needed
var clients = make(map[*websocket.Conn]client) // Note: although large maps with pointer-like types (e.g. strings) as keys are slow, using pointers themselves as keys is acceptable and fast
var register = make(chan *websocket.Conn)
var broadcast = make(chan string)
var unregister = make(chan *websocket.Conn)
func runHub() {
for {
select {
case connection := <-register:
clients[connection] = client{}
log.Println("connection registered")
case message := <-broadcast:
log.Println("message received:", message)
// Send the message to all clients
for connection := range clients {
if err := connection.WriteMessage(websocket.TextMessage, []byte(message)); err != nil {
log.Println("write error:", err)
unregister <- connection
connection.WriteMessage(websocket.CloseMessage, []byte{})
connection.Close()
}
}
case connection := <-unregister:
// Remove the client from the hub
delete(clients, connection)
log.Println("connection unregistered")
}
}
}
func main() {
app := fiber.New()
app.Static("/", "./home.html")
app.Use(func(c *fiber.Ctx) {
if websocket.IsWebSocketUpgrade(c) { // Returns true if the client requested upgrade to the WebSocket protocol
c.Next()
}
})
go runHub()
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
// When the function returns, unregister the client and close the connection
defer func() {
unregister <- c
c.Close()
}()
// Register the client
register <- c
for {
messageType, message, err := c.ReadMessage()
if err != nil {
if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {
log.Println("read error:", err)
}
return // Calls the deferred function, i.e. closes the connection on error
}
if messageType == websocket.TextMessage {
// Broadcast the received message
broadcast <- string(message)
} else {
log.Println("websocket message received of type", messageType)
}
}
}))
addr := flag.String("addr", ":8080", "http service address")
flag.Parse()
app.Listen(*addr)
}