forked from cryptowatch/cw-sdk-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
150 lines (122 loc) · 3.7 KB
/
main.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
143
144
145
146
147
148
149
150
/*
This is a simple app that allows to subscribe to and receive updates
for a given list of subscriptions.
*/
package main
import (
"log"
"os"
"os/signal"
"syscall"
"github.com/alunir/cw-sdk-go/client/websocket"
"github.com/alunir/cw-sdk-go/common"
"github.com/alunir/cw-sdk-go/config"
flag "github.com/spf13/pflag"
)
func main() {
// We need this since getting user's home dir can fail.
defaultConfig, err := config.DefaultFilepath()
if err != nil {
log.Print(err)
os.Exit(1)
}
var (
configPath string
verbose bool
subs []string
)
flag.StringVarP(&configPath, "config", "c", defaultConfig, "Configuration file")
flag.BoolVarP(&verbose, "verbose", "v", false, "Prints all debug messages to stdout")
flag.StringSliceVarP(&subs, "sub", "s", []string{}, "Subscription key. This flag can be given multiple times")
flag.Parse()
if len(subs) == 0 {
log.Printf("Error: at least one subscription must be spicified")
os.Exit(1)
}
cfg, err := config.NewFromPath(configPath)
if err != nil {
log.Print(err)
os.Exit(1)
}
streamSubs := make([]*websocket.StreamSubscription, 0, len(subs))
for _, s := range subs {
streamSubs = append(streamSubs, &websocket.StreamSubscription{Resource: s})
}
// Setup market connection (but don't connect just yet).
c, err := websocket.NewStreamClient(&websocket.StreamClientParams{
WSParams: &websocket.WSParams{
URL: cfg.StreamURL,
APIKey: cfg.APIKey,
SecretKey: cfg.SecretKey,
},
Subscriptions: streamSubs,
})
if err != nil {
log.Print(err)
os.Exit(1)
}
signals := make(chan os.Signal, 1)
// Will print state changes to the user.
if verbose {
lastErrChan := make(chan error, 1)
c.OnError(func(err error, disconnecting bool) {
// If the client is going to disconnect because of that error, just save
// the error to show later on the disconnection message.
if disconnecting {
lastErrChan <- err
return
}
// Otherwise, print the error message right away.
log.Printf("Error: %s", err)
})
c.OnStateChange(
websocket.ConnStateAny,
func(oldState, state websocket.ConnState) {
select {
case err := <-lastErrChan:
if err != nil {
log.Printf("State updated: %s -> %s: %s", websocket.ConnStateNames[oldState], websocket.ConnStateNames[state], err)
} else {
log.Printf("State updated: %s -> %s", websocket.ConnStateNames[oldState], websocket.ConnStateNames[state])
}
default:
log.Printf("State updated: %s -> %s", websocket.ConnStateNames[oldState], websocket.ConnStateNames[state])
}
},
)
c.OnBandwidthUpdate(func(b websocket.Bandwidth) {
log.Println(b)
if !b.OK {
signals <- syscall.SIGQUIT
}
})
}
// Will print received market update messages.
c.OnMarketUpdate(func(marketID common.MarketID, update common.MarketUpdate) {
log.Printf("Update on market %d: %+v", marketID, update)
})
c.OnPairUpdate(func(pair common.Pair, update common.PairUpdate) {
log.Printf("Pair update on pair %s: %+v", pair.ID, update)
})
c.OnSubscriptionResult(func(result websocket.SubscriptionResult) {
log.Printf("Subscription result: %+v", result)
})
c.OnUnsubscriptionResult(func(result websocket.UnsubscriptionResult) {
log.Printf("Unsubscription result: %+v\n", result)
})
if verbose {
log.Printf("Connecting to %s ...", c.URL())
}
// Finally, connect.
if err := c.Connect(); err != nil {
log.Print(err)
os.Exit(1)
}
signal.Notify(signals, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGTERM)
// Wait until the OS signal is received, at which point we'll close the connection and quit.
<-signals
log.Print("Closing connection...")
// The connection could already be closed, which would throw an error,
// but we can swallow it
c.Close()
}