/
client.go
99 lines (85 loc) · 2.58 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
package majordomo
import (
"fmt"
"time"
zmq "github.com/alecthomas/gozmq"
)
type mdClient struct {
broker string
client *zmq.Socket
context *zmq.Context
retries int
timeout time.Duration
}
func newClient(broker string, retries int, timeout time.Duration) (Client, error) {
context, err := zmq.NewContext()
if err != nil {return nil, err}
client := &mdClient{
broker: broker,
context: context,
retries: retries,
timeout: timeout,
}
err = client.connectToBroker()
return client, err
}
func (self *mdClient) connectToBroker() (err error) {
if self.client != nil {
err = self.client.Close()
if err != nil {return}
}
self.client, err = self.context.NewSocket(zmq.REQ)
if err != nil {return}
err = self.client.SetSockOptInt(zmq.LINGER, 0)
if err != nil {return}
err = self.client.Connect(self.broker)
return
}
func (self *mdClient) Close() (err error) {
if self.client != nil {
err = self.client.Close()
if err != nil {return err}
}
self.context.Close()
return
}
func (self *mdClient) Send(service string, request [][]byte) (reply [][]byte, err error) {
frame := append([][]byte{[]byte(MDPC_CLIENT), []byte(service)}, request...)
for retries := self.retries; retries > 0; retries -- {
if err != nil {
err = self.connectToBroker()
if err != nil {continue}
}
err = self.client.SendMultipart(frame, 0)
if err != nil {continue}
items := zmq.PollItems{
zmq.PollItem{Socket: self.client, Events: zmq.POLLIN},
}
_, err = zmq.Poll(items, self.timeout)
if err != nil {continue}
if item := items[0]; item.REvents&zmq.POLLIN != 0 {
msg, e := self.client.RecvMultipart(0)
if e != nil {err = e; continue}
if len(msg) < 3 {
err = fmt.Errorf("Invalid msg length %d", len(msg))
continue
}
header := msg[0]
if string(header) != MDPC_CLIENT {
err = fmt.Errorf("Incorrect header: %s, expected: %s", header, MDPC_CLIENT)
continue
}
replyService := msg[1]
if string(service) != string(replyService) {
err = fmt.Errorf("Incorrect reply service: %s, expected: %s", service, replyService)
continue
}
reply = msg[2:]
err = nil
return
} else {
err = fmt.Errorf("Poll timeout")
}
}
return
}