feat: initial commit

This commit is contained in:
2024-07-30 14:28:39 +02:00
commit 4729c54076
39 changed files with 3850 additions and 0 deletions

View File

@ -0,0 +1,137 @@
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
}

View File

@ -0,0 +1,38 @@
package socketio
import (
"net"
"strconv"
"strings"
gosocketio "forge.cadoles.com/Pyxis/golang-socketio"
"github.com/pkg/errors"
)
func EndpointFromHAddr(addr string) (string, error) {
host, rawPort, err := net.SplitHostPort(addr)
if err != nil {
var addrErr *net.AddrError
if !errors.As(err, &addrErr) || !strings.Contains(addrErr.Error(), "missing port in address") {
return "", errors.WithStack(err)
}
host = addr
}
port := int64(80)
if rawPort != "" {
port, err = strconv.ParseInt(rawPort, 10, 32)
if err != nil {
return "", errors.WithStack(err)
}
}
endpoint := Endpoint(host, int(port), false)
return endpoint, nil
}
func Endpoint(host string, port int, secure bool) string {
return gosocketio.GetUrl(host, port, false)
}

View File

@ -0,0 +1,62 @@
package socketio
import "time"
type Options struct {
PingInterval time.Duration
PingTimeout time.Duration
ReceiveTimeout time.Duration
SendTimeout time.Duration
BufferSize int
}
type OptionFunc func(opts *Options)
func NewOptions(funcs ...OptionFunc) *Options {
opts := &Options{
PingInterval: 5 * time.Second,
PingTimeout: 60 * time.Second,
ReceiveTimeout: 60 * time.Second,
SendTimeout: 60 * time.Second,
BufferSize: 1024 * 32,
}
for _, fn := range funcs {
fn(opts)
}
return opts
}
// WithPingInterval configures the client to use the given ping interval
func WithPingInterval(interval time.Duration) OptionFunc {
return func(opts *Options) {
opts.PingInterval = interval
}
}
// WithPingTimeout configures the client to use the given ping timeout
func WithPingTimeout(timeout time.Duration) OptionFunc {
return func(opts *Options) {
opts.PingTimeout = timeout
}
}
// WithReceiveTimeout configures the client to use the given receive timeout
func WithReceiveTimeout(timeout time.Duration) OptionFunc {
return func(opts *Options) {
opts.ReceiveTimeout = timeout
}
}
// WithSendTimeout configures the client to use the given send timeout
func WithSendTimeout(timeout time.Duration) OptionFunc {
return func(opts *Options) {
opts.SendTimeout = timeout
}
}
// WithBufferSize configures the client to use the given buffer size
func WithBufferSize(size int) OptionFunc {
return func(opts *Options) {
opts.BufferSize = size
}
}