/
web_socket.go
135 lines (115 loc) · 2.84 KB
/
web_socket.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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package coreapi
import (
"fmt"
"log"
"net/http"
"sort"
"github.com/gin-gonic/gin"
"github.com/gorilla/websocket"
)
var webSocketChannel = make(chan WebSocketPayload)
var clients = make(map[WebSocketConnection]string)
var uConn = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
CheckOrigin: func(r *http.Request) bool { return true },
}
type WebSocketConnection struct {
*websocket.Conn
}
type WebSocketResponse struct {
Action string `json:"action"`
Message string `json:"message"`
MessageType string `json:"message_type"`
ConnectedUsers []string `json:"connected_users"`
}
type WebSocketPayload struct {
Action string `json:"action"`
Username string `json:"username"`
Message string `json:"Message"`
Conn WebSocketConnection `json:"-"`
}
func (s *Server) WebSocketEndpoint(ctx *gin.Context) {
conn, err := uConn.Upgrade(ctx.Writer, ctx.Request, nil)
if err != nil {
log.Println(err)
}
//defer conn.Close()
log.Println("Client connected to endpoint")
response := WebSocketResponse{
Message: "<em><small>Connected to server.</small></em>",
}
cn := WebSocketConnection{conn}
clients[cn] = ""
err = conn.WriteJSON(response)
if err != nil {
log.Println(err)
}
go ListenForWebSocket(&cn)
}
func ListenForWebSocket(conn *WebSocketConnection) {
fmt.Println("Listening...")
defer func() {
if r := recover(); r != nil {
log.Println("Error ", fmt.Sprintf("%v", r))
}
}()
var payload WebSocketPayload
for {
err := conn.ReadJSON(&payload)
if err != nil {
// do nothing
} else {
payload.Conn = *conn
webSocketChannel <- payload
}
}
}
func ListenToWebSocketChannel() {
var response WebSocketResponse
for {
e := <-webSocketChannel
switch e.Action {
case "username":
clients[e.Conn] = e.Username
users := getUserList()
response.Action = "list_users"
response.ConnectedUsers = users
broadcastToAll(response)
case "left":
response.Action = "list_users"
delete(clients, e.Conn)
users := getUserList()
response.ConnectedUsers = users
broadcastToAll(response)
case "broadcast":
response.Action = "broadcast"
response.Message = fmt.Sprintf("<strong>%s</strong>: %s", e.Username, e.Message)
broadcastToAll(response)
}
// response.Action = "got here"
// response.Message = fmt.Sprintf("Some message, and action was %s", e.Action)
// broadcastToAll(response)
}
}
func getUserList() []string {
var userList []string
for _, x := range clients {
if x != "" {
userList = append(userList, x)
}
}
sort.Strings(userList)
return userList
}
func broadcastToAll(response WebSocketResponse) {
for client := range clients {
err := client.WriteJSON(response)
if err != nil {
log.Println("websocket error")
log.Println(err)
_ = client.Close()
delete(clients, client)
}
}
}