From 354c52b55d4a650052bdcd70c5a472f1e7c2a816 Mon Sep 17 00:00:00 2001 From: Sagleft Date: Wed, 25 May 2022 04:11:46 +0300 Subject: [PATCH] add websocket conn logic --- go.mod | 5 ++++- go.sum | 6 ++++++ request.go | 13 +++++++++++-- ws.go | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 76 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 5114a41..e175851 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,7 @@ module github.com/Sagleft/utopialib-go go 1.16 -require gopkg.in/grignaak/tribool.v1 v1.0.0-20150312065122-d6bb19d816df +require ( + github.com/sacOO7/gowebsocket v0.0.0-20210515122958-9396f1a71e23 // indirect + gopkg.in/grignaak/tribool.v1 v1.0.0-20150312065122-d6bb19d816df +) diff --git a/go.sum b/go.sum index 6498b29..b955387 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,8 @@ +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/sacOO7/go-logger v0.0.0-20180719173527-9ac9add5a50d h1:5T+fbRuQbpi+WZtB2yfuu59r00F6T2HV/zGYrwX8nvE= +github.com/sacOO7/go-logger v0.0.0-20180719173527-9ac9add5a50d/go.mod h1:L5EJe2k8GwpBoGXDRLAEs58R239jpZuE7NNEtW+T7oo= +github.com/sacOO7/gowebsocket v0.0.0-20210515122958-9396f1a71e23 h1:yjnkNJTpQPCx10KF1jypuIhAVc6EYn2M9lJgwSTHQYs= +github.com/sacOO7/gowebsocket v0.0.0-20210515122958-9396f1a71e23/go.mod h1:h00QywbM5Le22ESUiI8Yz2/9TVGD8eAz/cAk55Kcz/E= gopkg.in/grignaak/tribool.v1 v1.0.0-20150312065122-d6bb19d816df h1:SCh+kVSG+MN/pU/l0/3ehkc3i9T+G6AQS6jEoxM4ddY= gopkg.in/grignaak/tribool.v1 v1.0.0-20150312065122-d6bb19d816df/go.mod h1:ikoZVciJt+u3It4kEk89OVqIKHPU9BjrgkHSr++TA2w= diff --git a/request.go b/request.go index 11f2026..462fa3f 100644 --- a/request.go +++ b/request.go @@ -13,9 +13,18 @@ import ( "gopkg.in/grignaak/tribool.v1" ) +// get API url +func (c *UtopiaClient) getBaseURL() string { + return c.Protocol + "://" + c.getBaseURLWithoutProtocol() +} + +// get API url +func (c *UtopiaClient) getBaseURLWithoutProtocol() string { + return c.Host + ":" + strconv.Itoa(c.Port) + "/api/1.0/" +} + func (c *UtopiaClient) apiQuery(methodName string, params map[string]interface{}) (map[string]interface{}, error) { var responseMap map[string]interface{} - url := c.Protocol + "://" + c.Host + ":" + strconv.Itoa(c.Port) + "/api/1.0/" var query = Query{ Method: methodName, Token: c.Token, @@ -29,7 +38,7 @@ func (c *UtopiaClient) apiQuery(methodName string, params map[string]interface{} return responseMap, errors.New("failed to dedcode response json: " + err.Error()) } - req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr)) + req, err := http.NewRequest("POST", c.getBaseURL(), bytes.NewBuffer(jsonStr)) if err != nil { return responseMap, err } diff --git a/ws.go b/ws.go index e8817ba..8d0097c 100644 --- a/ws.go +++ b/ws.go @@ -1,8 +1,13 @@ package utopiago import ( + "encoding/json" "errors" + "os" + "os/signal" "reflect" + + "github.com/sacOO7/gowebsocket" ) // GetString - get string field from ws event. @@ -84,3 +89,53 @@ func (ws *WsEvent) GetFloat(field string) (float64, error) { return val, nil } + +type WsEventsCallback func(ws WsEvent) + +type WsErrorCallback func(err error) + +type WsSubscribeTask struct { + Callback WsEventsCallback // required + ErrCallback WsErrorCallback // required +} + +func newWsEvent(jsonRaw string) (WsEvent, error) { + event := WsEvent{} + err := json.Unmarshal([]byte(jsonRaw), &event) + if err != nil { + return event, errors.New("failed to decode event json: " + err.Error()) + } + return event, nil +} + +// WsSubscribe - connect to websocket & recive messages. +// NOTE: it's blocking method +func (c *UtopiaClient) WsSubscribe(task WsSubscribeTask) error { + interrupt := make(chan os.Signal, 1) + signal.Notify(interrupt, os.Interrupt) + + // create ws + socket := gowebsocket.New("ws://" + c.getBaseURLWithoutProtocol()) + + // setup callbacks + socket.OnTextMessage = func(message string, socket gowebsocket.Socket) { + event, err := newWsEvent(message) + if err != nil { + task.ErrCallback(err) + } else { + task.Callback(event) + } + } + + socket.OnDisconnected = func(err error, socket gowebsocket.Socket) { + task.ErrCallback(err) + } + + // connect + socket.Connect() + + // wait for close + <-interrupt + socket.Close() + return nil +}