Files
gocryptotrader/exchanges/okex/okex_websocket.go
2018-08-05 15:15:21 +02:00

151 lines
4.6 KiB
Go

package okex
import (
"fmt"
"log"
"net/http"
"strings"
"time"
"github.com/gorilla/websocket"
"github.com/thrasher-/gocryptotrader/common"
)
const (
okexDefaultWebsocketURL = "wss://real.okex.com:10440/websocket/okexapi"
)
func (o *OKEX) writeToWebsocket(message string) error {
o.mu.Lock()
defer o.mu.Unlock()
return o.WebsocketConn.WriteMessage(websocket.TextMessage, []byte(message))
}
func (o *OKEX) websocketConnect() {
var Dialer websocket.Dialer
var err error
myEnabledSubscriptionChannels := []string{}
for _, pair := range o.EnabledPairs {
myEnabledSubscriptionChannels = append(myEnabledSubscriptionChannels, fmt.Sprintf("{'event':'addChannel','channel':'ok_sub_spot_%s_ticker'}", pair))
myEnabledSubscriptionChannels = append(myEnabledSubscriptionChannels, fmt.Sprintf("{'event':'addChannel','channel':'ok_sub_spot_%s_depth'}", pair))
myEnabledSubscriptionChannels = append(myEnabledSubscriptionChannels, fmt.Sprintf("{'event':'addChannel','channel':'ok_sub_spot_%s_deals'}", pair))
myEnabledSubscriptionChannels = append(myEnabledSubscriptionChannels, fmt.Sprintf("{'event':'addChannel','channel':'ok_sub_spot_%s_kline_1min'}", pair))
}
mySubscriptionString := "[" + strings.Join(myEnabledSubscriptionChannels, ",") + "]"
o.WebsocketConn, _, err = Dialer.Dial(okexDefaultWebsocketURL, http.Header{})
if err != nil {
log.Printf("%s Unable to connect to Websocket. Error: %s\n", o.Name, err)
return
}
if o.Verbose {
log.Printf("%s Connected to Websocket.\n", o.Name)
log.Printf("Subscription String is %s\n", mySubscriptionString)
}
log.Printf("Subscription String is %s\n", mySubscriptionString)
// subscribe to all the desired subscriptions
err = o.writeToWebsocket(mySubscriptionString)
if err != nil {
log.Printf("Error: Could not subscribe to the OKEX websocket %s", err)
return
}
}
// WebsocketClient the main function handling the OKEX websocket
// Documentation URL: https://github.com/okcoin-okex/API-docs-OKEx.com/blob/master/API-For-Spot-EN/WEBSOCKET%20API%20for%20SPOT.md
func (o *OKEX) WebsocketClient() {
for o.Enabled && o.Websocket {
o.websocketConnect()
go func() {
for {
time.Sleep(time.Second * 27)
o.writeToWebsocket("{'event':'ping'}")
log.Printf("%s sent Ping message\n", o.GetName())
}
}()
for o.Enabled && o.Websocket {
msgType, resp, err := o.WebsocketConn.ReadMessage()
if err != nil {
log.Printf("Error: Could not read from the OKEX websocket %s", err)
o.websocketConnect()
continue
}
switch msgType {
case websocket.TextMessage:
multiStreamDataArr := []MultiStreamData{}
err = common.JSONDecode(resp, &multiStreamDataArr)
if err != nil {
if strings.Contains(string(resp), "pong") {
log.Printf("%s received Pong message\n", o.GetName())
} else {
log.Printf("%s some other error happened: %s", o.GetName(), err)
continue
}
}
for _, multiStreamData := range multiStreamDataArr {
if strings.Contains(multiStreamData.Channel, "ticker") {
// ticker data
ticker := TickerStreamData{}
tickerDecodeError := common.JSONDecode(multiStreamData.Data, &ticker)
if tickerDecodeError != nil {
log.Printf("OKEX Ticker Decode Error: %s", tickerDecodeError)
continue
}
log.Printf("OKEX Channel: %s\tData: %s\n", multiStreamData.Channel, multiStreamData.Data)
} else if strings.Contains(multiStreamData.Channel, "deals") {
// orderbook data
deals := DealsStreamData{}
decodeError := common.JSONDecode(multiStreamData.Data, &deals)
if decodeError != nil {
log.Printf("OKEX Deals Decode Error: %s", decodeError)
continue
}
log.Printf("OKEX Channel: %s\tData: %s\n", multiStreamData.Channel, multiStreamData.Data)
} else if strings.Contains(multiStreamData.Channel, "kline") {
// 1 min kline data
klines := KlineStreamData{}
decodeError := common.JSONDecode(multiStreamData.Data, &klines)
if decodeError != nil {
log.Printf("OKEX Klines Decode Error: %s", decodeError)
continue
}
log.Printf("OKEX Channel: %s\tData: %s\n", multiStreamData.Channel, multiStreamData.Data)
} else if strings.Contains(multiStreamData.Channel, "depth") {
// market depth data
depth := DepthStreamData{}
decodeError := common.JSONDecode(multiStreamData.Data, &depth)
if decodeError != nil {
log.Printf("OKEX Depth Decode Error: %s", decodeError)
continue
}
log.Printf("OKEX Channel: %s\tData: %s\n", multiStreamData.Channel, multiStreamData.Data)
}
}
}
}
}
}