-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathtcp.go
121 lines (114 loc) · 2.78 KB
/
tcp.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
/*
* @Author: yhlyl
* @Date: 2019-11-03 11:12:44
* @LastEditTime: 2019-11-05 14:24:10
* @LastEditors: yhlyl
* @Description:
* @FilePath: /gin_micro/tcp/tcp.go
* @Github: https://github.com/android-coco/gin_micro
*/
package tcp
import (
"encoding/json"
"fmt"
"gin_micro/config"
"gin_micro/httpserver/wss/proto"
"gin_micro/model"
socket "gin_micro/socket/tcp"
"gin_micro/util"
jasonlog "gin_micro/util/log"
"gin_micro/util/uuid"
"log"
"time"
protoutil "github.com/gogo/protobuf/proto"
)
func Run(address string) {
err := socket.InitConn(address, func(conn *socket.Connection) {
defer conn.Close()
client(conn)
})
if err != nil {
log.Fatalf("tcp err:%v", err)
}
}
func client(conn *socket.Connection) {
//TODO 服务器判断
currentClient := &model.TCPClient{
Id: uuid.NewUUID().Hex32(),
Uid: 100,
Ip: conn.GetIP(),
Conn: conn,
MessageChan: make(chan interface{}, 0),
IsOnLine: true,
OnLineTime: time.Now().Format("2006-01-02T15:04:05.000"),
OfflineTime: "",
}
fmt.Println(currentClient.Id)
//加入map
model.ClientList.Store(currentClient.Id, currentClient)
go heartBeat(currentClient)
readMsg(currentClient)
}
// 读客户端消息
func readMsg(currentClient *model.TCPClient) {
defer currentClient.ReleaseClient()
for {
var (
data []byte
err error
)
data, err = currentClient.Conn.ReadMessage()
// TODO 客服端数据 要处理
//fmt.Println(len(data),string(data), err)
if err != nil {
// 连接错误
jasonlog.Errorf("读取错误:err:%v", err)
return
}
cmd := util.IsCheckCmd(data, currentClient.Uid)
if !cmd {
jasonlog.Errorf("数据包错误:err:%v", err)
//TODO 返回错误到客户端
return
}
var msg proto.Msg
err = protoutil.Unmarshal(data[8:len(data)-2], &msg)
dataCallBack, _ := protoutil.Marshal(&msg)
log.Print("服务端recvMsg:\n", msg, string(msg.Data))
err = currentClient.Conn.WriteMessage(0x01, dataCallBack, currentClient.Uid)
if err != nil {
jasonlog.Errorf("回复错误:%v", err)
// 回复错误
break
}
}
}
// 心跳包
func heartBeat(currentClient *model.TCPClient) {
ticker := time.NewTicker(time.Duration(config.GetWss().HeartbeatTime) * time.Second)
defer ticker.Stop()
defer currentClient.ReleaseClient()
for {
select {
case <-ticker.C:
heart := model.Heartbeat{
TimeStr: time.Now().Format("2006-01-02 15:04:05"),
}
dataByte, _ := json.Marshal(heart)
//心跳
msg := &proto.Msg{
ErrorNo: util.SuccessCode,
ErrorMsg: "",
Data: dataByte,
}
data, _ := protoutil.Marshal(msg)
fmt.Println("写数据:", data)
err := currentClient.Conn.WriteMessage(0x00, data, currentClient.Uid)
if err != nil {
fmt.Println(err)
// 某个客户端异常退出
return
}
}
}
}