/
cloud_ws_contract.go
142 lines (118 loc) · 2.62 KB
/
cloud_ws_contract.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 bitmart
import (
_ "bytes"
_ "compress/flate"
"encoding/json"
"errors"
"github.com/gorilla/websocket"
_ "io/ioutil"
"log"
_ "runtime/debug"
_ "time"
)
type CloudWSContract struct {
CloudWS
}
func NewWSContract(config Config) *CloudWSContract {
var ws CloudWSContract
ws.Config = config
return &ws
}
var pingMsg = &struct {
Subscribe string
}{
"ping",
}
type Msg struct {
Action string
Args []string
}
type RespMsg struct {
Action string
Success bool
}
// SubscribeWithLogin Support public channel and private channel
func (ws *CloudWSContract) SubscribeWithLogin(channels []string) {
if err := ws.login(); err != nil {
log.Fatalf("Login Err: %s", err)
return
}
ws.reconnectUseLogin = true
ws.reconnectUseChannels = channels
if err := ws.subscribe(Msg{
Action: "subscribe",
Args: channels,
}); err != nil {
ws.stop()
}
}
// SubscribeWithoutLogin Only support public channel
func (ws *CloudWSContract) SubscribeWithoutLogin(channels []string) {
ws.reconnectUseLogin = false
ws.reconnectUseChannels = channels
if err := ws.subscribe(Msg{
Action: "subscribe",
Args: channels,
}); err != nil {
ws.stop()
}
}
// login
func (ws *CloudWSContract) login() error {
timestamp := UTCTime()
sign, err := HmacSha256Base64Signer(
PreHashString(timestamp, ws.Config.Memo, "bitmart.WebSocket"), ws.Config.SecretKey)
if err != nil {
return err
}
loginParam, err := json.Marshal(Msg{
Action: "access",
Args: []string{ws.Config.ApiKey, timestamp, sign, "web"},
})
if err != nil {
return errors.New("login param convert json error")
}
if ws.Config.IsPrint {
log.Printf("Send Msg: %s", loginParam)
}
if err := ws.Conn.WriteMessage(websocket.TextMessage, loginParam); err != nil {
log.Printf("Send Msg Err: %s", err)
return err
}
_, message, err := ws.Conn.ReadMessage()
if err != nil {
log.Printf("Read Err: %s", err)
}
var result RespMsg
if err := json.Unmarshal(message, &result); err == nil {
if result.Success != true {
ws.stop()
return errors.New(string(message))
}
}
return nil
}
// subscribe
func (ws *CloudWSContract) subscribe(msg Msg) error {
message, err := json.Marshal(msg)
if err != nil {
return errors.New("json convert string error")
}
if ws.Config.IsPrint {
log.Printf("Send Msg: %s", message)
}
if err := ws.Conn.WriteMessage(websocket.TextMessage, message); err != nil {
log.Printf("Send Msg Err: %s", err)
return err
}
go ws.work()
go ws.receive()
go ws.finalize()
return nil
}
// keepalive
func (ws *CloudWSContract) keepalive() {
if err := ws.Conn.WriteJSON(pingMsg); err != nil {
log.Printf("Send Msg Err: %s", err)
}
}