-
Notifications
You must be signed in to change notification settings - Fork 3
/
client.go
130 lines (117 loc) · 2.72 KB
/
client.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
/*
* @Author: 时光弧线
* @Date: 2017-12-30 11:54:57
* @Last Modified by: 时光弧线
* @Last Modified time: 2017-12-30 13:11:34
*/
package tcplibrary
import (
"context"
"crypto/tls"
"errors"
"net"
"time"
)
/* tcp golang客户端 */
// TCPClient tcp客户端
type TCPClient struct {
*TCPLibrary
pingData interface{} // ping时的包
conn *Conn // 连接对象
}
// NewTCPClient 创建一个tcp客户端
func NewTCPClient(debug bool, socket Socket, packets ...Packet) (*TCPClient, error) {
if socket == nil {
return nil, errors.New("Socket参数不能是nil")
}
// 封包解包对象
var packet Packet
if len(packets) == 0 {
packet = NewDefaultPacket()
} else {
packet = packets[0]
}
// 请求上下文
ctx, cancel := context.WithCancel(context.Background())
return &TCPClient{
TCPLibrary: &TCPLibrary{
ctx: ctx,
cancel: cancel,
packet: packet,
socket: socket,
readDeadline: DefaultReadDeadline,
readBufferSize: DefaultBufferSize,
isServer: false,
},
}, nil
}
// DialAndStart 连接到服务器,并开始读取信息
func (c *TCPClient) DialAndStart(address string) error {
conn, err := net.Dial("tcp", address)
if err != nil {
globalLogger.Errorf(err.Error())
return err
}
return c.Dial(conn)
}
// DialAndStartTLS 连接到服务器,并开始读取信息 tls
func (c *TCPClient) DialAndStartTLS(address string) error {
conf := &tls.Config{
InsecureSkipVerify: true,
}
conn, err := tls.Dial("tcp", address, conf)
if err != nil {
globalLogger.Errorf(err.Error())
return err
}
return c.Dial(conn)
}
// Dial 连接tcp服务端
func (c *TCPClient) Dial(conn net.Conn) error {
// 判断是否设置读超时
if c.readDeadline == 0 {
c.readDeadline = DefaultReadDeadline
}
// 赋值给当前连接对象
c.conn = &Conn{
Conn: conn,
connType: TCPSocketType,
packet: c.packet,
}
// 通知建立连接
err := c.socket.OnConnect(c.conn)
if err != nil {
globalLogger.Errorf(err.Error())
// 如果建立连接函数返回false,则关闭连接
c.socket.OnClose(c.conn, err) // 通知关闭
err = conn.Close() // 关闭连接
if err != nil {
globalLogger.Errorf(err.Error())
}
return err
}
// 开启一个协程处理数据接收
go c.handleConn(c.conn)
return nil
}
// GetConn 获取连接对象
func (c *TCPClient) GetConn() *Conn {
return c.conn
}
// Ping 保活
func (c *TCPClient) Ping(v interface{}) {
go func() {
for {
_, err := c.conn.SendMessage(v)
if err != nil {
globalLogger.Errorf("client ping error", err)
return
}
if DefaultReadDeadline < 3*time.Second {
time.Sleep(1 * time.Second)
} else {
time.Sleep(DefaultReadDeadline / 3 * 2)
}
}
}()
}