var (
apiConnection *websocket.Conn
apiConnected = false
)
func connectApi() *websocket.Conn {
u := url.URL{Scheme: "ws", Host: *addr, Path: "/ws"}
log.Printf("connecting to %s", u.String())
for {
log.Println("reconnecting")
var err error
apiConnection, _, err = websocket.DefaultDialer.Dial(u.String(), nil)
if err != nil {
apiConnected = false
log.Println("dial: ", err)
time.Sleep(4 * time.Second)
continue
}
log.Println("API connected")
break
}
apiConnected = true
return apiConnection
}
func main() {
log.SetFlags(0)
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt)
// Connect to API
apiConnection = connectApi()
defer apiConnection.Close()
done := make(chan struct{})
go func() {
defer apiConnection.Close()
defer close(done)
for {
_, message, err := apiConnection.ReadMessage()
if err != nil {
log.Println("read: ", err)
apiConnected = false
apiConnection = connectApi()
defer apiConnection.Close()
return
}
log.Printf("recv: %s", message)
}
}()
for {
select {
case command := <-commands:
log.Println(command)
err := apiConnection.WriteMessage(websocket.TextMessage, command)
if err != nil {
log.Println("command err: ", err)
return
}
case <-interrupt:
log.Println("interrupt")
// To cleanly close a connection, a client should send a close
// frame and wait for the server to close the connection.
err := apiConnection.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
if err != nil {
log.Println("write close: ", err)
return
}
select {
case <-done:
case <-time.After(time.Second):
}
apiConnected = false
apiConnection.Close()
return
}
}
}