Base de client ReachRS fonctionnelle

This commit is contained in:
2018-09-18 18:07:40 +02:00
parent 267017bdc1
commit cd27332c4f
12 changed files with 1188 additions and 6 deletions

View File

@ -0,0 +1,26 @@
package reach
import (
"github.com/pkg/errors"
)
const (
// EventBrowserConnected is emitted after the initial connection to the
// ReachView endpoint
EventBrowserConnected = "browser connected"
)
// sendBrowserConnected notifies the ReachView endpoint
// of a new connection.
// See misc/reachview/update_main.js line 297
func (c *Client) sendBrowserConnected() error {
payload := map[string]string{
"data": "I'm connected",
}
c.logf("sending '%s' event", EventBrowserConnected)
if err := c.conn.Emit(EventBrowserConnected, payload); err != nil {
return errors.Wrapf(err, "error while emitting '%s' event", EventBrowserConnected)
}
c.logf("'%s' event sent", EventBrowserConnected)
return nil
}

99
reach/client.go Normal file
View File

@ -0,0 +1,99 @@
package reach
import (
"sync"
"time"
"forge.cadoles.com/Pyxis/golang-socketio"
"forge.cadoles.com/Pyxis/golang-socketio/transport"
"github.com/pkg/errors"
)
type handshake struct {
PingInterval time.Duration `json:"pingInterval"`
}
// Client is a ReachView Websocket API client
type Client struct {
opts *Options
conn *gosocketio.Client
}
// Connect connects the client to the ReachView endpoint
// This method is not safe to call by different coroutines
func (c *Client) Connect() error {
var err error
var wg sync.WaitGroup
wg.Add(1)
transport := &transport.WebsocketTransport{
PingInterval: c.opts.PingInterval,
PingTimeout: c.opts.PingTimeout,
ReceiveTimeout: c.opts.ReceiveTimeout,
SendTimeout: c.opts.SendTimeout,
BufferSize: c.opts.BufferSize,
}
c.logf("connecting to '%s'", c.opts.Endpoint)
conn, err := gosocketio.Dial(c.opts.Endpoint, transport)
if err != nil {
return errors.Wrap(err, "error while connecting to endpoint")
}
c.conn = conn
err = conn.On(gosocketio.OnConnection, func(h *gosocketio.Channel) {
c.logf("connected with sid '%s'", h.Id())
err = c.sendBrowserConnected()
wg.Done()
})
if err != nil {
return errors.Wrap(err, "error while attaching to connection event")
}
err = conn.On(gosocketio.OnError, func(h *gosocketio.Channel) {
c.logf("error")
err = errors.Errorf("an unknown error occured")
c.conn = nil
wg.Done()
})
if err != nil {
return errors.Wrap(err, "error while attaching to error event")
}
wg.Wait()
conn.On(gosocketio.OnError, nil)
return err
}
// Close closes the current connection to the ReachView endpoint
func (c *Client) Close() {
if c.conn == nil {
return
}
c.conn.Close()
c.conn = nil
return
}
func (c *Client) logf(format string, args ...interface{}) {
if c.opts.Logger == nil {
return
}
c.opts.Logger.Printf(format, args...)
}
// NewClient returns a new ReachView Websocket API client
func NewClient(opts ...OptionFunc) *Client {
options := DefaultOptions()
for _, o := range opts {
o(options)
}
return &Client{
opts: options,
}
}

27
reach/client_test.go Normal file
View File

@ -0,0 +1,27 @@
package reach
import (
"testing"
)
func TestClient(t *testing.T) {
client := NewClient(
WithStandardLogger(),
)
if err := client.Connect(); err != nil {
t.Fatal(err)
}
results, err := client.TestResults()
if err != nil {
t.Error(err)
}
if g, e := results.Device, "ReachRS"; g != e {
t.Errorf("results.Device: got '%s', expected '%s'", g, e)
}
defer client.Close()
}

91
reach/option.go Normal file
View File

@ -0,0 +1,91 @@
package reach
import (
"log"
"os"
"time"
"forge.cadoles.com/Pyxis/golang-socketio"
)
type Logger interface {
Printf(format string, args ...interface{})
}
// Options are ReachRS client configuration options
type Options struct {
Endpoint string
PingInterval time.Duration
PingTimeout time.Duration
ReceiveTimeout time.Duration
SendTimeout time.Duration
BufferSize int
Logger Logger
}
type OptionFunc func(opts *Options)
func WithEndpoint(host string, port int) OptionFunc {
return func(opts *Options) {
opts.Endpoint = gosocketio.GetUrl(host, port, false)
}
}
func WithPingInterval(interval time.Duration) OptionFunc {
return func(opts *Options) {
opts.PingInterval = interval
}
}
func WithPingTimeout(timeout time.Duration) OptionFunc {
return func(opts *Options) {
opts.PingTimeout = timeout
}
}
func WithReceiveTimeout(timeout time.Duration) OptionFunc {
return func(opts *Options) {
opts.ReceiveTimeout = timeout
}
}
func WithSendTimeout(timeout time.Duration) OptionFunc {
return func(opts *Options) {
opts.SendTimeout = timeout
}
}
func WithBufferSize(size int) OptionFunc {
return func(opts *Options) {
opts.BufferSize = size
}
}
func WithLogger(logger Logger) OptionFunc {
return func(opts *Options) {
opts.Logger = logger
}
}
func WithStandardLogger() OptionFunc {
return func(opts *Options) {
logger := log.New(os.Stdout, "[reachrs] ", log.LstdFlags)
opts.Logger = logger
}
}
func DefaultOptions() *Options {
opts := &Options{}
defaults := []OptionFunc{
WithEndpoint("192.168.42.1", 80),
WithPingInterval(30 * time.Second),
WithPingTimeout(60 * time.Second),
WithReceiveTimeout(60 * time.Second),
WithSendTimeout(60 * time.Second),
WithBufferSize(1024 * 32),
}
for _, o := range defaults {
o(opts)
}
return opts
}

37
reach/probe.go Normal file
View File

@ -0,0 +1,37 @@
package reach
import (
"sync"
"forge.cadoles.com/Pyxis/golang-socketio"
"github.com/pkg/errors"
)
const (
// EventProbe -
EventProbe = "probe"
)
// Probe -
func (c *Client) Probe() error {
var wg sync.WaitGroup
wg.Add(1)
c.conn.On(EventProbe, func(h *gosocketio.Channel) {
wg.Done()
c.conn.On(EventProbe, nil)
})
c.logf("sending '%s' event", EventProbe)
if err := c.conn.Emit(EventProbe, nil); err != nil {
return errors.Wrapf(err, "error while emitting '%s' event", EventProbe)
}
c.logf("'%s' event sent", EventProbe)
wg.Wait()
return nil
}

51
reach/test_results.go Normal file
View File

@ -0,0 +1,51 @@
package reach
import (
"sync"
"forge.cadoles.com/Pyxis/golang-socketio"
"github.com/pkg/errors"
)
const (
// EventGetTestResults is a request for the ReachRS module's test results
EventGetTestResults = "get test results"
// EventTestResults is the response of the EventGetTestResults request
EventTestResults = "test results"
)
// TestResults are the ReachRS module's test results
type TestResults struct {
UBlox bool `json:"u-blox"`
STC bool `json:"stc"`
MPU bool `json:"mpu"`
Device string `json:"device"`
Lora bool `json:"lora"`
}
// TestResults returns the ReachRS module tests results
func (c *Client) TestResults() (*TestResults, error) {
var err error
var results *TestResults
var wg sync.WaitGroup
wg.Add(1)
c.conn.On(EventTestResults, func(h *gosocketio.Channel, res *TestResults) {
results = res
c.conn.On(EventTestResults, nil)
wg.Done()
})
c.logf("sending '%s' event", EventGetTestResults)
if err = c.conn.Emit(EventGetTestResults, nil); err != nil {
return nil, errors.Wrapf(err, "error while emitting '%s' event", EventGetTestResults)
}
c.logf("'%s' event sent", EventGetTestResults)
wg.Wait()
return results, err
}