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 }