Update .gitreview file
[src/xds/xds-cli.git] / iosocket-client.go
1 /*
2  * Copyright (C) 2018 "IoT.bzh"
3  * Author Sebastien Douheret <sebastien@iot.bzh>
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *   http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18
19 package main
20
21 import (
22         "fmt"
23         "sync"
24
25         "gerrit.automotivelinux.org/gerrit/src/xds/xds-agent.git/lib/xaapiv1"
26
27         socketio_client "github.com/sebd71/go-socket.io-client"
28 )
29
30 // Disconnection Channel used to notify XDS Server disconnection
31 type Disconnection struct {
32         error   string
33         code    int
34         svrConf xaapiv1.ServerCfg
35 }
36
37 // IOSockClient .
38 type IOSockClient struct {
39         URL             string
40         Conn            *socketio_client.Client
41         Options         *socketio_client.Options
42         EmitMutex       *sync.Mutex
43         Connected       bool
44         ServerDiscoChan chan Disconnection
45         EscapeKeys      []byte
46 }
47
48 // NewIoSocketClient Create a new IOSockClient
49 func NewIoSocketClient(url, clientID string) (*IOSockClient, error) {
50
51         var err error
52
53         sCli := &IOSockClient{
54                 URL:       url,
55                 EmitMutex: &sync.Mutex{},
56                 Options: &socketio_client.Options{
57                         Transport: "websocket",
58                         Header:    make(map[string][]string),
59                 },
60                 ServerDiscoChan: make(chan Disconnection, 1),
61         }
62         sCli.Options.Header["XDS-AGENT-SID"] = []string{clientID}
63
64         sCli.Conn, err = socketio_client.NewClient(url, sCli.Options)
65         if err != nil {
66                 return nil, fmt.Errorf("IO.socket connection error: " + err.Error())
67         }
68
69         sCli.Conn.On("connection", func() {
70                 sCli.Connected = true
71         })
72
73         sCli.Conn.On("disconnection", func(err error) {
74                 Log.Debugf("WS disconnection event with err: %v\n", err)
75                 sCli.Connected = false
76         })
77
78         args := xaapiv1.EventRegisterArgs{Name: xaapiv1.EVTServerConfig}
79         if err := HTTPCli.Post("/events/register", args, nil); err != nil {
80                 return sCli, err
81         }
82
83         sCli.Conn.On(xaapiv1.EVTServerConfig, func(ev xaapiv1.EventMsg) {
84                 svrCfg, err := ev.DecodeServerCfg()
85                 if err == nil && !svrCfg.Connected {
86                         sCli.ServerDiscoChan <- Disconnection{
87                                 error:   "\nXDS Server (id " + svrCfg.ID + ") disconnected !",
88                                 code:    1,
89                                 svrConf: svrCfg,
90                         }
91                 }
92         })
93
94         return sCli, nil
95 }
96
97 // On record a callback on a specific message
98 func (c *IOSockClient) On(message string, f interface{}) (err error) {
99         return c.Conn.On(message, f)
100 }
101
102 // Emit send a message
103 func (c *IOSockClient) Emit(message string, args ...interface{}) (err error) {
104         c.EmitMutex.Lock()
105         defer c.EmitMutex.Unlock()
106         return c.Conn.Emit(message, args...)
107 }