-
Notifications
You must be signed in to change notification settings - Fork 0
/
client.go
142 lines (115 loc) · 3.14 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
131
132
133
134
135
136
137
138
139
140
141
142
package socketgo
import (
"net"
"os"
"os/signal"
"syscall"
)
type Client struct {
conn net.Conn
protocol IPacketProtocol
stopedChan <-chan os.Signal
}
func NewClient(protocol IPacketProtocol) *Client {
stopSignal := make(chan os.Signal) // 接收系统中断信号
var shutdownSignals = []os.Signal{os.Interrupt, syscall.SIGTERM, syscall.SIGINT}
signal.Notify(stopSignal, shutdownSignals...)
return &Client{
stopedChan: stopSignal,
protocol: protocol,
}
}
func (c *Client) Conn(network, address string, readBufferSize, writeBufferSize int) error {
conn, err := net.Dial(network, address)
if err != nil {
return nil
}
c.conn = conn
tcpConn := conn.(*net.TCPConn)
_ = tcpConn.SetNoDelay(true)
_ = tcpConn.SetReadBuffer(readBufferSize)
_ = tcpConn.SetWriteBuffer(writeBufferSize)
return nil
}
func (c *Client) Send(packet interface{}) error {
select {
case <-c.stopedChan:
return ErrSignalStopped
default:
content := c.protocol.BuildPacket(packet)
err := c.protocol.SendPacket(c.conn, content)
if err != nil {
return ErrWritePacketFailed
}
}
return nil
}
func (c *Client) Recv() (interface{}, error) {
packet, err := c.protocol.ReadPacket(c.conn)
if err != nil {
return nil, ErrReadPacketFailed
}
return packet, nil
}
// AsyncClient 异步通讯客户端
type AsyncClient struct {
Client
sendChanSize int
session ISession
dispatcher IDispatcher
}
func NewAsyncClient(protocol IPacketProtocol, dispatcher IDispatcher, bufferSize int) *AsyncClient {
stopSignal := make(chan os.Signal) // 接收系统中断信号
var shutdownSignals = []os.Signal{os.Interrupt, syscall.SIGTERM, syscall.SIGINT}
signal.Notify(stopSignal, shutdownSignals...)
return &AsyncClient{
Client: Client{
stopedChan: stopSignal,
protocol: protocol,
},
sendChanSize: bufferSize,
dispatcher: dispatcher,
}
}
// GetDispatcher 获取事件分发器
func (c *AsyncClient) GetDispatcher() IDispatcher {
return c.dispatcher
}
// GetSession 获取会话信息
func (c *AsyncClient) GetSession() ISession {
return c.session
}
// Close 关闭连接
func (c *AsyncClient) Close() {
if nil != c.session {
_ = c.session.Close()
}
}
// Conn 与服务器建立TCP连接
// :Param network: 网络类型: "tcp"、"udp"
// :Param address: 链接的地址: "IP:PORT"
func (c *AsyncClient) Conn(network, address string,
readBufferSize, writeBufferSize int,
callbackSend FnCallbackSended, callbackClosed FnCallbackClosed) error {
err := c.Client.Conn(network, address, readBufferSize, writeBufferSize)
if err != nil {
return nil
}
c.session = NewSession(c.conn, c.protocol, c.dispatcher.HandleProc, c.sendChanSize)
if callbackSend != nil {
c.session.SetSendCallback(callbackSend)
}
if callbackClosed != nil {
c.session.SetCloseCallback(callbackClosed)
}
c.session.Start()
return nil
}
func (c *AsyncClient) Send(packet interface{}) error {
return c.session.Send(packet)
}
// Recv 异步通讯的客户端只能注册接收消息的句柄,不能直接收取封包内容
func (c *AsyncClient) Recv() (interface{}, error) {
panic("异步通讯客户端不允许直接读取封包内容")
return nil, ErrReadPacketFailed
}