-
Notifications
You must be signed in to change notification settings - Fork 1
/
safe_ws.go
75 lines (67 loc) · 1.72 KB
/
safe_ws.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
package pbbot
import (
"github.com/ProtobufBot/go-pbbot/util"
"github.com/gorilla/websocket"
log "github.com/sirupsen/logrus"
)
// safe websocket
type SafeWebSocket struct {
Conn *websocket.Conn
SendChannel chan *WebSocketSendingMessage
OnRecvMessage func(messageType int, data []byte)
OnClose func(int, string)
}
type WebSocketSendingMessage struct {
MessageType int
Data []byte
}
func (ws *SafeWebSocket) Send(messageType int, data []byte) {
ws.SendChannel <- &WebSocketSendingMessage{
MessageType: messageType,
Data: data,
}
}
func NewSafeWebSocket(conn *websocket.Conn, OnRecvMessage func(messageType int, data []byte), onClose func(int, string)) *SafeWebSocket {
ws := &SafeWebSocket{
Conn: conn,
SendChannel: make(chan *WebSocketSendingMessage, 100),
OnRecvMessage: OnRecvMessage,
OnClose: onClose,
}
conn.SetCloseHandler(func(code int, text string) error {
ws.OnClose(code, text)
return nil
})
// 接受消息
util.SafeGo(func() {
for {
messageType, data, err := conn.ReadMessage()
if err != nil {
log.Errorf("failed to read message, err: %+v", err)
_ = conn.Close()
return
}
if messageType == websocket.PingMessage {
ws.Send(websocket.PongMessage, []byte("pong"))
continue
}
ws.OnRecvMessage(messageType, data)
}
})
// 发送消息
util.SafeGo(func() {
for sendingMessage := range ws.SendChannel {
if ws.Conn == nil {
log.Errorf("failed to send websocket message, conn is nil")
return
}
err := ws.Conn.WriteMessage(sendingMessage.MessageType, sendingMessage.Data)
if err != nil {
log.Errorf("failed to send websocket message, %+v", err)
_ = conn.Close()
return
}
}
})
return ws
}