diff options
-rw-r--r-- | cmd/dolmetschctl/dolmetschctl.go | 61 | ||||
-rw-r--r-- | pkg/types/types.go | 46 |
2 files changed, 99 insertions, 8 deletions
diff --git a/cmd/dolmetschctl/dolmetschctl.go b/cmd/dolmetschctl/dolmetschctl.go index 1d8c6ad..fb8cdf3 100644 --- a/cmd/dolmetschctl/dolmetschctl.go +++ b/cmd/dolmetschctl/dolmetschctl.go @@ -23,23 +23,73 @@ package main import ( + "encoding/json" + "fmt" + "io" + "io/ioutil" "log" "os" "time" "github.com/gorilla/websocket" "spreadspace.org/dolmetschctl/pkg/controller" - // "spreadspace.org/dolmetschctl/pkg/types" + "spreadspace.org/dolmetschctl/pkg/types" ) -func run(c *controller.Controller, ws *websocket.Conn) error { - ch := make(chan controller.Event, 100) - c.Subscribe(ch) +func wsReader(ws *websocket.Conn, ch chan<- types.WebSocketResponseFull) { + defer close(ch) + + for { + t, r, err := ws.NextReader() + if err != nil { + log.Println("websocket disconnected:", err) + return + } + + switch t { + case websocket.TextMessage: + var msg types.WebSocketResponseFull + dec := json.NewDecoder(r) + dec.DisallowUnknownFields() + if err := dec.Decode(&msg); err != nil { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + log.Println("webclient response parse error:", err) + return + } + + ch <- msg + case websocket.BinaryMessage: + io.Copy(ioutil.Discard, r) // consume all the data + } + } + return +} + +func run(ctrl *controller.Controller, ws *websocket.Conn) error { + ctrlCh := make(chan controller.Event, 100) + ctrl.Subscribe(ctrlCh) + + wsCh := make(chan types.WebSocketResponseFull) + go wsReader(ws, wsCh) + + if err := ws.WriteJSON(types.WebSocketRequest{Command: "subscribe"}); err != nil { + return err + } for { select { - case ev := <-ch: + case ev, ok := <-ctrlCh: + if !ok { + return fmt.Errorf("controller channel was closed.") + } log.Printf("got controller event: %v", ev) + case msg, ok := <-wsCh: + if !ok { + return fmt.Errorf("websocket channel was closed.") + } + log.Printf("got message from websocket: %v", msg) } } return nil @@ -66,7 +116,6 @@ func main() { if err != nil { log.Printf("Error connecting to daemon: %v", err) } else { - err := run(c, ws) log.Printf("run() returned: %v", err) } diff --git a/pkg/types/types.go b/pkg/types/types.go index 601f818..4747db6 100644 --- a/pkg/types/types.go +++ b/pkg/types/types.go @@ -22,6 +22,10 @@ package types +import ( + "fmt" +) + // State Machine type State int @@ -45,11 +49,29 @@ func (s State) String() string { } } +func (s *State) FromString(str string) error { + switch str { + case "new": + *s = StateNew + case "settling": + *s = StateSettling + case "settled": + *s = StateSettled + default: + return fmt.Errorf("invalid state '%s'", str) + } + return nil +} + func (s State) MarshalText() (data []byte, err error) { data = []byte(s.String()) return } +func (s *State) UnmarshalText(data []byte) error { + return s.FromString(string(data)) +} + type Language string func (l Language) String() string { @@ -59,11 +81,24 @@ func (l Language) String() string { return string(l) } -func (s Language) MarshalText() (data []byte, err error) { - data = []byte(s.String()) +func (l *Language) FromString(str string) error { + if str == "none" { + *l = "" + } else { + *l = Language(str) + } + return nil +} + +func (l Language) MarshalText() (data []byte, err error) { + data = []byte(l.String()) return } +func (l *Language) UnmarshalText(data []byte) error { + return l.FromString(string(data)) +} + type FullState struct { State State Ratio float32 @@ -111,3 +146,10 @@ type WebSocketResponseLanguages struct { WebSocketResponseBase Languages []Language `json:"languages"` } + +type WebSocketResponseFull struct { + WebSocketResponseBase + ErrorString string `json:"error"` + WebState + Languages []Language `json:"languages"` +} |