This repository has been archived on 2022-11-30. You can view files and clone it, but cannot push or open issues or pull requests.
tacitus/gdax/websocket/client.go
2017-09-24 22:23:13 -07:00

124 lines
2.0 KiB
Go

package websocket
import (
"github.com/gorilla/websocket"
"github.com/kcotugno/tacitus/gdax"
"sync"
"time"
)
const ENDPOINT = "wss://ws-feed.gdax.com"
type Client struct {
msgs chan gdax.Message
err chan error
writer chan gdax.Request
conn *websocket.Conn
conMux sync.Mutex
connect bool
close chan bool
}
func NewClient() *Client {
c := Client{}
c.writer = make(chan gdax.Request)
c.close = make(chan bool)
return &c
}
func (c *Client) Open() error {
var err error
c.conn, _, err = websocket.DefaultDialer.Dial(ENDPOINT, nil)
if err != nil {
return err
}
c.setConnected(true)
c.msgs = make(chan gdax.Message, 1024)
c.err = make(chan error)
go func() {
for c.connected() {
var msg gdax.Message
err := c.conn.ReadJSON(&msg)
if err != nil {
if websocket.IsUnexpectedCloseError(err,
websocket.CloseNormalClosure) {
c.sendClose(false)
c.err <- err
break
}
}
c.msgs <- msg
}
close(c.msgs)
close(c.err)
}()
go func() {
for c.connected() {
select {
case msg := <-c.writer:
err := c.conn.WriteJSON(msg)
if err != nil {
c.sendClose(false)
c.err <- err
}
case send := <-c.close:
if send {
c.conn.WriteControl(websocket.CloseMessage,
websocket.FormatCloseMessage(websocket.CloseNormalClosure,
"done"),
time.Now().Add(30*time.Second))
}
}
}
}()
return nil
}
func (c *Client) Close() {
c.sendClose(true)
}
func (c *Client) sendClose(send bool) {
if c.connected() {
c.setConnected(false)
c.close <- send
}
}
func (c *Client) Send(msg gdax.Request) {
if c.connected() {
c.writer <- msg
}
}
func (c *Client) Stream() <-chan gdax.Message {
return c.msgs
}
func (c *Client) Error() <-chan error {
return c.err
}
func (c *Client) connected() bool {
c.conMux.Lock()
defer c.conMux.Unlock()
return c.connect
}
func (c *Client) setConnected(connected bool) {
c.conMux.Lock()
defer c.conMux.Unlock()
c.connect = connected
}