-
Notifications
You must be signed in to change notification settings - Fork 16
/
hWebSocket.go
153 lines (144 loc) · 3.05 KB
/
hWebSocket.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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package microSocket
import (
"bufio"
"bytes"
"crypto/sha1"
"encoding/base64"
"encoding/binary"
"io"
"log"
"microSocket/util"
"strings"
)
type WebSocket struct {
}
//ws接收消息
func (this *WebSocket) ConnHandle(msf *Msf, sess *Session) {
defer func() {
msf.SessionMaster.DelSessionById(sess.Id)
//调用断开链接事件
msf.EventPool.OnClose(sess.Id)
}()
if this.Handshake(sess) == false {
return
}
var (
buf []byte
err error
fin byte
opcode byte
mask byte
mKey []byte
length uint64
l uint16
payload byte
tembuf []byte
)
for {
buf = make([]byte, 2)
_, err = io.ReadFull(sess.Con, buf)
if err != nil {
break
}
fin = buf[0] >> 7
opcode = buf[0] & 0xf
if opcode == 8 {
break
}
mask = buf[1] >> 7
payload = buf[1] & 0x7f
switch {
case payload < 126:
length = uint64(payload)
case payload == 126:
buf = make([]byte, 2)
io.ReadFull(sess.Con, buf)
binary.Read(bytes.NewReader(buf), binary.BigEndian, &l)
length = uint64(l)
case payload == 127:
buf = make([]byte, 8)
io.ReadFull(sess.Con, buf)
binary.Read(bytes.NewReader(buf), binary.BigEndian, &length)
}
if mask == 1 {
mKey = make([]byte, 4)
io.ReadFull(sess.Con, mKey)
}
buf = make([]byte, length)
io.ReadFull(sess.Con, buf)
if mask == 1 {
for i, v := range buf {
buf[i] = v ^ mKey[i%4]
}
}
//更新最近接收到消息的时间
sess.updateTime()
if len(buf) == 0 {
continue
}
tembuf = append(tembuf,buf...)
if fin == 0 {
continue
}
//把请求的到数据转化为map
requestData := util.String2Map(string(tembuf))
tembuf = make([]byte,0)
//路由调用
if msf.Hook(sess.Id,requestData) == false {
return
}
}
}
//websocket 打包事件
func (this *WebSocket) Pack(data []byte) []byte {
length := len(data)
frame := []byte{129}
switch {
case length < 126:
frame = append(frame, byte(length))
case length <= 0xffff:
buf := make([]byte, 2)
binary.BigEndian.PutUint16(buf, uint16(length))
frame = append(frame, byte(126))
frame = append(frame, buf...)
case uint64(length) <= 0xffffffffffffffff:
buf := make([]byte, 8)
binary.BigEndian.PutUint64(buf, uint64(length))
frame = append(frame, byte(127))
frame = append(frame, buf...)
default:
return []byte{}
}
frame = append(frame, data...)
return frame
}
//握手包
func (this *WebSocket) Handshake(sess *Session) bool {
reader := bufio.NewReader(sess.Con)
key := ""
str := ""
for {
line, _, err := reader.ReadLine()
if err != nil {
log.Fatal(err)
return false
}
if len(line) == 0 {
break
}
str = string(line)
if strings.HasPrefix(str, "Sec-WebSocket-Key") {
key = str[19:43]
}
}
sha := sha1.New()
io.WriteString(sha, key+"258EAFA5-E914-47DA-95CA-C5AB0DC85B11")
key = base64.StdEncoding.EncodeToString(sha.Sum(nil))
header := "HTTP/1.1 101 Switching Protocols\r\n" +
"Connection: Upgrade\r\n" +
"Sec-WebSocket-Version: 13\r\n" +
"Sec-WebSocket-Accept: " + key + "\r\n" +
"Upgrade: websocket\r\n\r\n"
sess.Con.Write([]byte(header))
return true
}