/
dog_client.go
106 lines (92 loc) · 2.28 KB
/
dog_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
/**
* Copyright 2018 gd Author. All Rights Reserved.
* Author: Chuck1024
*/
package dogrpc
import (
"bufio"
"crypto/tls"
"encoding/json"
dogError "github.com/chuck1024/gd/derror"
"github.com/chuck1024/gd/dlog"
"io"
"math/rand"
"net"
"time"
)
/*
* dog client
*/
// dog packet establish connection
func (c *RpcClient) DogConnect() (*Client, error) {
addr := &net.TCPAddr{}
if len(c.addrs) > 0 {
rand.Seed(time.Now().UnixNano())
idx := rand.Intn(len(c.addrs))
addr = c.addrs[idx]
} else {
return nil, InternalServerError
}
cc, ok := c.Cm[addr.String()]
if !ok {
c.cmMutex.Lock()
defer c.cmMutex.Unlock()
if cc, ok = c.Cm[addr.String()]; !ok {
cc = &Client{
Addr: addr.String(),
RequestTimeout: time.Millisecond * time.Duration(c.Timeout),
Encoder: func(w io.Writer, bufferSize int) (encoder MessageEncoder, err error) {
return &DogPacketEncoder{bw: bufio.NewWriterSize(w, bufferSize)}, nil
},
Decoder: func(r io.Reader, bufferSize int) (decoder MessageDecoder, err error) {
return &DogPacketDecoder{br: bufio.NewReaderSize(r, bufferSize)}, nil
},
}
if c.TlsCfg != nil {
cc.Dial = func(addr string) (conn io.ReadWriteCloser, err error) {
c, err := tls.DialWithDialer(dialer, DefaultDialNetWork, addr, c.TlsCfg)
if err != nil {
return nil, err
}
return c, err
}
}
cc.Start()
c.Cm[addr.String()] = cc
} else {
dlog.Warn("Addr %s already created.", addr)
}
} else {
if cc.clientStopChan == nil {
cc.Start()
}
}
return cc, nil
}
// dog packet. Invoke rpc call
func (c *RpcClient) DogInvoke(cmd uint32, req interface{}, client ...*Client) (code uint32, rsp []byte, err *dogError.CodeError) {
var ct *Client
if len(client) == 0 {
cc, err := c.DogConnect()
if err != nil {
dlog.Error("Invoke connect occur error:%s", err)
return code, nil, InternalServerError
}
ct = cc
} else {
ct = client[0]
}
var body []byte
if req != nil {
body, _ = json.Marshal(req)
}
var reqPkt, rspPkt Packet
reqPkt = NewDogPacket(cmd, body)
if rspPkt, err = ct.CallRetry(reqPkt, c.RetryNum); err != nil {
dlog.Error("Invoke CallRetry occur error:%v ", err)
return code, nil, err
}
rsp = rspPkt.(*DogPacket).Body
code = rspPkt.(*DogPacket).ErrCode
return code, rsp, nil
}