138 lines
2.6 KiB
Go
138 lines
2.6 KiB
Go
|
package socketio
|
||
|
|
||
|
import (
|
||
|
"sync"
|
||
|
|
||
|
gosocketio "forge.cadoles.com/Pyxis/golang-socketio"
|
||
|
"forge.cadoles.com/Pyxis/golang-socketio/transport"
|
||
|
"github.com/pkg/errors"
|
||
|
)
|
||
|
|
||
|
type Channel = gosocketio.Channel
|
||
|
|
||
|
const (
|
||
|
OnDisconnection = gosocketio.OnDisconnection
|
||
|
OnConnection = gosocketio.OnConnection
|
||
|
OnError = gosocketio.OnError
|
||
|
)
|
||
|
|
||
|
type Client struct {
|
||
|
conn *gosocketio.Client
|
||
|
mutex sync.RWMutex
|
||
|
endpoint string
|
||
|
opts *Options
|
||
|
}
|
||
|
|
||
|
func (c *Client) Connect() error {
|
||
|
c.mutex.Lock()
|
||
|
defer c.mutex.Unlock()
|
||
|
|
||
|
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,
|
||
|
}
|
||
|
|
||
|
conn, err := gosocketio.Dial(c.endpoint, transport)
|
||
|
if err != nil {
|
||
|
return errors.Wrap(err, "error while connecting to endpoint")
|
||
|
}
|
||
|
|
||
|
c.conn = nil
|
||
|
|
||
|
cleanup := func() {
|
||
|
conn.Off(gosocketio.OnError)
|
||
|
conn.Off(gosocketio.OnConnection)
|
||
|
}
|
||
|
|
||
|
err = conn.On(gosocketio.OnConnection, func(h *Channel) {
|
||
|
cleanup()
|
||
|
wg.Done()
|
||
|
})
|
||
|
if err != nil {
|
||
|
return errors.Wrap(err, "error while attaching to connection event")
|
||
|
}
|
||
|
|
||
|
err = conn.On(gosocketio.OnError, func(h *Channel) {
|
||
|
cleanup()
|
||
|
err = errors.Errorf("an unknown error occured")
|
||
|
wg.Done()
|
||
|
})
|
||
|
if err != nil {
|
||
|
return errors.Wrap(err, "error while attaching to error event")
|
||
|
}
|
||
|
|
||
|
wg.Wait()
|
||
|
|
||
|
c.conn = conn
|
||
|
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
func (c *Client) Close() {
|
||
|
c.mutex.Lock()
|
||
|
defer c.mutex.Unlock()
|
||
|
|
||
|
if c.conn == nil {
|
||
|
return
|
||
|
}
|
||
|
c.conn.Close()
|
||
|
c.conn = nil
|
||
|
}
|
||
|
|
||
|
func (c *Client) Alive() bool {
|
||
|
c.mutex.RLock()
|
||
|
defer c.mutex.RUnlock()
|
||
|
|
||
|
if c.conn == nil {
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
return c.conn.IsAlive()
|
||
|
}
|
||
|
|
||
|
// Emit a new event with the given data
|
||
|
func (c *Client) Emit(event string, data any) error {
|
||
|
c.mutex.RLock()
|
||
|
defer c.mutex.RUnlock()
|
||
|
|
||
|
if err := c.conn.Emit(event, data); err != nil {
|
||
|
return errors.Wrapf(err, "error while emitting '%s' event", event)
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
type Handler func(ch *Channel, data any)
|
||
|
|
||
|
// On binds and event handler to the given event
|
||
|
func (c *Client) On(event string, handler Handler) error {
|
||
|
c.mutex.RLock()
|
||
|
defer c.mutex.RUnlock()
|
||
|
|
||
|
return c.conn.On(event, handler)
|
||
|
}
|
||
|
|
||
|
// Off remove the handler bound to the given event
|
||
|
func (c *Client) Off(event string) {
|
||
|
c.mutex.RLock()
|
||
|
defer c.mutex.RUnlock()
|
||
|
|
||
|
c.conn.Off(event)
|
||
|
}
|
||
|
|
||
|
func NewClient(endpoint string, funcs ...OptionFunc) *Client {
|
||
|
opts := NewOptions(funcs...)
|
||
|
client := &Client{
|
||
|
endpoint: endpoint,
|
||
|
opts: opts,
|
||
|
}
|
||
|
return client
|
||
|
}
|