Base de client ReachRS fonctionnelle
This commit is contained in:
26
reach/browser_connected.go
Normal file
26
reach/browser_connected.go
Normal 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
99
reach/client.go
Normal 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
27
reach/client_test.go
Normal 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
91
reach/option.go
Normal 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
37
reach/probe.go
Normal 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
51
reach/test_results.go
Normal 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
|
||||
|
||||
}
|
Reference in New Issue
Block a user