1 package Network
2
3 import (
4 "logs"
5 "time"
6 "token"
7
8 "github.com/gorilla/websocket"
9 )
10
11 type ClientData struct {
12 conn *websocket.Conn
13 token string
14 }
15
16 var wsClients = make(map[string]ClientData)
17
18 // 是否在线
19 func isOnline(clientID string) bool {
20 lock.RLock()
21 _, isOnline := wsClients[clientID]
22 lock.RUnlock()
23 return isOnline
24 }
25
26 // --------------------------------------------- 连接管理部分
27
28 // 增加WebSocket连接
29 func addClient(clientID string, con *websocket.Conn) (canAdd bool) {
30
31 if isOnline(clientID) {
32 writeResponseToClient(clientID, ServerResponse{
33 Method: "/wsLogin",
34 Code: noticeForceQuit,
35 Message: mForceQuit,
36 Result: nil,
37 })
38 deleteClient(clientID)
39 time.Sleep(time.Millisecond) // 如果不睡眠或者睡眠时间太短,两个连接都会被同时关掉
40 logs.Print(clientID, mForceQuit)
41 addConnection(clientID, con)
42 return false
43 }
44 addConnection(clientID, con)
45 return true
46 }
47
48 func addConnection(clientID string, con *websocket.Conn) {
49 clientData := ClientData{
50 conn: con,
51 token: "",
52 }
53 token.New(clientID, &clientData.token, func() { //此函数用于每次token变化后将token写回客户端
54 //更新完client后才能writeResponse,注意死锁
55 lock.Lock()
56 wsClients[clientID] = clientData
57 lock.Unlock()
58 writeResponseToClient(clientID, ServerResponse{
59 Code: Success,
60 Method: "/token",
61 Message: "",
62 Result: map[string]string{"Token": clientData.token},
63 })
64 })
65 }
66
67 // 获取客户端连接
68 func getClient(clientID string) (clientConn *websocket.Conn, isOnline bool) {
69
70 lock.RLock()
71 clientData, ok := wsClients[clientID]
72 lock.RUnlock()
73 return clientData.conn, ok
74 }
75
76 // 删除WebSocket连接
77 func deleteClient(clientID string) {
78 clientData, ok := wsClients[clientID]
79 if !ok {
80 return
81 }
82 lock.Lock()
83 clientData.conn.Close()
84 token.Del(clientData.token)
85 delete(wsClients, clientID)
86 lock.Unlock()
87 }