socket

package module
v3.0.0-rc.13 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 26, 2026 License: MIT Imports: 17 Imported by: 0

README

Socket.IO Client for Go

Go Reference Go Report Card

A robust Go client implementation for Socket.IO, featuring real-time bidirectional event-based communication.

Features

  • Transport Support

    • WebSocket
    • HTTP long-polling
    • WebTransport (experimental)
    • Automatic transport upgrade
    • Fallback mechanism
  • Connection Management

    • Automatic reconnection with exponential backoff
    • Connection state handling
    • Multiple namespaces support
    • Room support
  • Event Handling

    • Event emitting and listening
    • Acknowledgements support
    • Volatile events
    • Binary data support
    • Custom event listeners
  • Advanced Features

    • Multiplexing
    • Custom middleware
    • Connection timeout handling
    • Debug logging

Installation

go get github.com/zishang520/socket.io/clients/socket/v3

Quick Start

Basic Connection
package main

import (
    "log"

    "github.com/zishang520/socket.io/clients/socket/v3"
)

func main() {
    client, err := socket.Connect("http://localhost:3000", nil)
    if err != nil {
        log.Fatal(err)
    }

    client.On("connect", func(...any) {
        log.Println("Connected!")
        client.Emit("message", "Hello Server!")
    })

    client.On("event", func(data ...any) {
        log.Printf("Received: %v", data)
    })

    select {}
}
Advanced Usage
package main

import (
    "time"

    "github.com/zishang520/socket.io/clients/socket/v3"
    "github.com/zishang520/socket.io/clients/engine/v3/transports"
    "github.com/zishang520/socket.io/v3/pkg/types"
)

func main() {
    opts := socket.DefaultOptions()
    opts.SetTransports(types.NewSet(
        transports.Polling,
        transports.WebSocket,
    ))
    opts.SetTimeout(5 * time.Second)
    opts.SetReconnection(true)
    opts.SetReconnectionAttempts(5)

    manager := socket.NewManager("http://localhost:3000", opts)

    // Custom namespace
    socket := manager.Socket("/custom", nil)

    // Event handling
    socket.On("connect", func(...any) {
        socket.Emit("auth", map[string]string{
            "token": "your-auth-token",
        })
    })

    // Acknowledgement
    socket.Emit("event", "data", func(args ...any) {
        log.Printf("Server acknowledged: %v", args)
    })

    // Listen to all events
    socket.OnAny(func(args ...any) {
        log.Printf("Caught event: %v", args)
    })
}

API Reference

Manager Options
opts := socket.DefaultManagerOptions()
opts.SetReconnection(true)                   // Enable/disable reconnection
opts.SetReconnectionAttempts(math.Inf(1))    // Number of reconnection attempts
opts.SetReconnectionDelay(1000)              // Initial delay in milliseconds
opts.SetReconnectionDelayMax(5000)           // Maximum delay between reconnections
opts.SetRandomizationFactor(0.5)             // Randomization factor for delays
opts.SetTimeout(20000)                       // Connection timeout
Socket Methods
  • Emit: socket.Emit(eventName string, args ...any)
  • On: socket.On(eventName string, fn func(...any))
  • Once: socket.Once(eventName string, fn func(...any))
  • Off: socket.Off(eventName string, fn func(...any))
  • OnAny: socket.OnAny(fn func(...any))
  • Connect: socket.Connect()
  • Disconnect: socket.Disconnect()
Events
  • connect: Fired upon connection
  • disconnect: Fired upon disconnection
  • connect_error: Fired upon connection error
  • reconnect: Fired upon successful reconnection
  • reconnect_attempt: Fired upon reconnection attempt
  • reconnect_error: Fired upon reconnection error
  • reconnect_failed: Fired when reconnection fails

Debugging

Enable debug logs:

import "github.com/zishang520/socket.io/v3/pkg/log"

log.DEBUG = true
make test

Testing

make test

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

MIT License - see LICENSE file for details.

Documentation

Overview

Package socket provides a Socket.IO client implementation in Go. It enables real-time, bidirectional event-based communication between web clients and servers.

Example usage:

socket, err := socket.Connect("http://localhost:8080", nil)
if err != nil {
    log.Fatal(err)
}
socket.On("connect", func() {
    socket.Emit("hello", "world")
})

Index

Examples

Constants

View Source
const VERSION = version.VERSION

Variables

View Source
var (
	RESERVED_EVENTS = types.NewSet("connect", "connect_error", "disconnect", "disconnecting", "newListener", "removeListener")

	Polling      = transports.Polling
	WebSocket    = transports.WebSocket
	WebTransport = transports.WebTransport
)

Functions

This section is empty.

Types

type Engine

type Engine = engine.Socket

type EngineOptions

type EngineOptions = engine.SocketOptions

ManagerOptionsInterface defines the configuration interface for a Socket.IO Manager. It extends EngineOptionsInterface and provides additional options for reconnection, multiplexing, timeouts, and parser selection.

type EngineOptionsInterface

type EngineOptionsInterface = engine.SocketOptionsInterface

ManagerOptionsInterface defines the configuration interface for a Socket.IO Manager. It extends EngineOptionsInterface and provides additional options for reconnection, multiplexing, timeouts, and parser selection.

type Flags

type Flags struct {
	packet.Options

	Volatile  bool           `json:"volatile" msgpack:"volatile"`
	Timeout   *time.Duration `json:"timeout,omitempty" msgpack:"timeout,omitempty"`
	FromQueue bool           `json:"fromQueue" msgpack:"fromQueue"`
}

Flags represents emission flags for a socket event, such as volatile, timeout, and queue status.

type Handshake

type Handshake struct {
	Sid string `json:"sid" msgpack:"sid"`
	Pid string `json:"pid,omitempty" msgpack:"pid,omitempty"`
}

Handshake contains information from the server handshake.

type Manager

type Manager struct {
	types.EventEmitter
	// contains filtered or unexported fields
}

Manager implements the Socket.IO client manager that handles connections to a Socket.IO server. It manages connection lifecycle, automatic reconnection, and socket namespaces.

Example usage:

opts := DefaultManagerOptions()
opts.SetTimeout(5 * time.Second)

manager, err := NewManager("http://localhost:8080", opts)
if err != nil {
    log.Fatal(err)
}

// Get a socket for the default namespace
socket := manager.Socket("/", nil)

func MakeManager

func MakeManager() *Manager

MakeManager creates a new Manager instance with default event emitter, namespace map, and subscriptions.

func NewManager

func NewManager(uri string, opts ManagerOptionsInterface) *Manager

NewManager creates a new Manager instance with the specified URI and options. It establishes and manages the connection to a Socket.IO server.

Parameters:

  • uri: The URI of the Socket.IO server (e.g., "http://localhost:8080")
  • opts: Configuration options for the manager

Returns:

  • *Manager: A new manager instance

func (*Manager) Connect

func (m *Manager) Connect(fn func(error)) *Manager

Alias for Manager.Open

func (*Manager) Construct

func (m *Manager) Construct(uri string, opts ManagerOptionsInterface)

Construct initializes the Manager instance with the given URI and options.

func (*Manager) Engine

func (m *Manager) Engine() Engine

Engine returns the underlying Engine.IO client instance.

func (*Manager) Open

func (m *Manager) Open(fn func(error)) *Manager

Open initiates the connection to the server. This is called automatically when autoConnect is true (default).

Parameters:

  • fn: Optional callback that will be called when connection is established or fails

Returns:

  • *Manager: The manager instance for chaining

func (*Manager) Opts

func (m *Manager) Opts() ManagerOptionsInterface

Opts returns the ManagerOptionsInterface for this manager.

func (*Manager) RandomizationFactor

func (m *Manager) RandomizationFactor() float64

func (*Manager) Reconnection

func (m *Manager) Reconnection() bool

func (*Manager) ReconnectionAttempts

func (m *Manager) ReconnectionAttempts() float64

func (*Manager) ReconnectionDelay

func (m *Manager) ReconnectionDelay() float64

func (*Manager) ReconnectionDelayMax

func (m *Manager) ReconnectionDelayMax() float64

func (*Manager) SetRandomizationFactor

func (m *Manager) SetRandomizationFactor(randomizationFactor float64)

Sets the maximum delay between reconnections.

func (*Manager) SetReconnection

func (m *Manager) SetReconnection(reconnection bool)

Sets the `reconnection` config.

func (*Manager) SetReconnectionAttempts

func (m *Manager) SetReconnectionAttempts(reconnectionAttempts float64)

Sets the reconnection attempts config.

func (*Manager) SetReconnectionDelay

func (m *Manager) SetReconnectionDelay(reconnectionDelay float64)

Sets the delay between reconnections.

func (*Manager) SetReconnectionDelayMax

func (m *Manager) SetReconnectionDelayMax(reconnectionDelayMax float64)

Sets the randomization factor

func (*Manager) SetTimeout

func (m *Manager) SetTimeout(timeout time.Duration)

Sets the connection timeout. `false` to disable

func (*Manager) Socket

func (m *Manager) Socket(nsp string, opts SocketOptionsInterface) *Socket

Socket creates or returns an existing Socket instance for the specified namespace.

Parameters:

  • nsp: The namespace to connect to (defaults to "/")
  • opts: Socket-specific options

Returns:

  • *Socket: A Socket instance for the namespace

func (*Manager) Timeout

func (m *Manager) Timeout() *time.Duration

type ManagerOptions

type ManagerOptions struct {
	EngineOptions
	// contains filtered or unexported fields
}

ManagerOptions holds configuration for a Socket.IO Manager instance.

func DefaultManagerOptions

func DefaultManagerOptions() *ManagerOptions

DefaultManagerOptions returns a new ManagerOptions instance with default values.

func (*ManagerOptions) Assign

Assign copies all options from another ManagerOptionsInterface instance. If data is nil, it returns the current ManagerOptions instance.

func (*ManagerOptions) AutoConnect

func (s *ManagerOptions) AutoConnect() bool

func (*ManagerOptions) ForceNew

func (s *ManagerOptions) ForceNew() bool

func (*ManagerOptions) GetRawAutoConnect

func (s *ManagerOptions) GetRawAutoConnect() types.Optional[bool]

func (*ManagerOptions) GetRawForceNew

func (s *ManagerOptions) GetRawForceNew() types.Optional[bool]

func (*ManagerOptions) GetRawMultiplex

func (s *ManagerOptions) GetRawMultiplex() types.Optional[bool]

func (*ManagerOptions) GetRawParser

func (s *ManagerOptions) GetRawParser() types.Optional[parser.Parser]

func (*ManagerOptions) GetRawPath

func (s *ManagerOptions) GetRawPath() types.Optional[string]

func (*ManagerOptions) GetRawRandomizationFactor

func (s *ManagerOptions) GetRawRandomizationFactor() types.Optional[float64]

func (*ManagerOptions) GetRawReconnection

func (s *ManagerOptions) GetRawReconnection() types.Optional[bool]

func (*ManagerOptions) GetRawReconnectionAttempts

func (s *ManagerOptions) GetRawReconnectionAttempts() types.Optional[float64]

func (*ManagerOptions) GetRawReconnectionDelay

func (s *ManagerOptions) GetRawReconnectionDelay() types.Optional[float64]

func (*ManagerOptions) GetRawReconnectionDelayMax

func (s *ManagerOptions) GetRawReconnectionDelayMax() types.Optional[float64]

func (*ManagerOptions) GetRawTimeout

func (s *ManagerOptions) GetRawTimeout() types.Optional[time.Duration]

func (*ManagerOptions) Multiplex

func (s *ManagerOptions) Multiplex() bool

func (*ManagerOptions) Parser

func (s *ManagerOptions) Parser() parser.Parser

func (*ManagerOptions) Path

func (s *ManagerOptions) Path() string

func (*ManagerOptions) RandomizationFactor

func (s *ManagerOptions) RandomizationFactor() float64

func (*ManagerOptions) Reconnection

func (s *ManagerOptions) Reconnection() bool

func (*ManagerOptions) ReconnectionAttempts

func (s *ManagerOptions) ReconnectionAttempts() float64

func (*ManagerOptions) ReconnectionDelay

func (s *ManagerOptions) ReconnectionDelay() float64

func (*ManagerOptions) ReconnectionDelayMax

func (s *ManagerOptions) ReconnectionDelayMax() float64

func (*ManagerOptions) SetAutoConnect

func (s *ManagerOptions) SetAutoConnect(autoConnect bool)

func (*ManagerOptions) SetForceNew

func (s *ManagerOptions) SetForceNew(forceNew bool)

func (*ManagerOptions) SetMultiplex

func (s *ManagerOptions) SetMultiplex(multiplex bool)

func (*ManagerOptions) SetParser

func (s *ManagerOptions) SetParser(parser parser.Parser)

func (*ManagerOptions) SetPath

func (s *ManagerOptions) SetPath(path string)

func (*ManagerOptions) SetRandomizationFactor

func (s *ManagerOptions) SetRandomizationFactor(randomizationFactor float64)

func (*ManagerOptions) SetReconnection

func (s *ManagerOptions) SetReconnection(reconnection bool)

func (*ManagerOptions) SetReconnectionAttempts

func (s *ManagerOptions) SetReconnectionAttempts(reconnectionAttempts float64)

func (*ManagerOptions) SetReconnectionDelay

func (s *ManagerOptions) SetReconnectionDelay(reconnectionDelay float64)

func (*ManagerOptions) SetReconnectionDelayMax

func (s *ManagerOptions) SetReconnectionDelayMax(reconnectionDelayMax float64)

func (*ManagerOptions) SetTimeout

func (s *ManagerOptions) SetTimeout(timeout time.Duration)

func (*ManagerOptions) Timeout

func (s *ManagerOptions) Timeout() time.Duration

type ManagerOptionsInterface

type ManagerOptionsInterface interface {
	EngineOptionsInterface

	SetForceNew(bool)
	GetRawForceNew() types.Optional[bool]
	ForceNew() bool

	SetMultiplex(bool)
	GetRawMultiplex() types.Optional[bool]
	Multiplex() bool

	SetPath(string)
	GetRawPath() types.Optional[string]
	Path() string

	SetReconnection(bool)
	GetRawReconnection() types.Optional[bool]
	Reconnection() bool

	SetReconnectionAttempts(float64)
	GetRawReconnectionAttempts() types.Optional[float64]
	ReconnectionAttempts() float64

	SetReconnectionDelay(float64)
	GetRawReconnectionDelay() types.Optional[float64]
	ReconnectionDelay() float64

	SetReconnectionDelayMax(float64)
	GetRawReconnectionDelayMax() types.Optional[float64]
	ReconnectionDelayMax() float64

	SetRandomizationFactor(float64)
	GetRawRandomizationFactor() types.Optional[float64]
	RandomizationFactor() float64

	SetTimeout(time.Duration)
	GetRawTimeout() types.Optional[time.Duration]
	Timeout() time.Duration

	SetAutoConnect(bool)
	GetRawAutoConnect() types.Optional[bool]
	AutoConnect() bool

	SetParser(parser.Parser)
	GetRawParser() types.Optional[parser.Parser]
	Parser() parser.Parser
}

ManagerOptionsInterface defines the configuration interface for a Socket.IO Manager.

type Options

type Options struct {
	ManagerOptions
	SocketOptions
}

Options holds both manager and socket options for a Socket.IO client.

func DefaultOptions

func DefaultOptions() *Options

DefaultOptions returns a new Options instance with default values.

func (*Options) Assign

func (s *Options) Assign(data OptionsInterface) OptionsInterface

Assign copies all options from another OptionsInterface instance. If data is nil, it returns the current Options instance.

type OptionsInterface

type OptionsInterface interface {
	ManagerOptionsInterface
	SocketOptionsInterface
}

OptionsInterface combines ManagerOptionsInterface and SocketOptionsInterface for unified configuration.

type Packet

type Packet struct {
	*parser.Packet

	Options *packet.Options `json:"options,omitempty" msgpack:"options,omitempty"`
}

Packet represents a Socket.IO packet, including options for encoding.

type QueuedPacket

type QueuedPacket struct {
	Id       uint64
	Args     []any
	Flags    *Flags
	Pending  atomic.Bool
	TryCount atomic.Int64
}

QueuedPacket represents a packet that is queued for guaranteed delivery with retry support. Id is for debugging; deduplication should use a unique offset.

type ReadyState

type ReadyState string

ReadyState represents the state of the connection.

const (
	// ReadyStateOpen indicates the connection is open.
	ReadyStateOpen ReadyState = "open"
	// ReadyStateOpening indicates the connection is in the process of opening.
	ReadyStateOpening ReadyState = "opening"
	// ReadyStateClosed indicates the connection is closed.
	ReadyStateClosed ReadyState = "closed"
)

type Socket

type Socket struct {
	types.EventEmitter
	// contains filtered or unexported fields
}

Socket represents a Socket.IO connection to a specific namespace. It implements an event-driven interface for real-time bidirectional communication.

Socket belongs to a specific namespace (default '/') and uses an underlying Manager for network communication. It supports event emission, acknowledgments, and automatic reconnection.

Example usage:

socket := io.Connect("http://localhost:8000", nil)

socket.On("connect", func() {
	fmt.Println("Connected!")
	// Send an event to the server
	socket.Emit("message", "Hello server!")
})

// Listen for server events
socket.On("reply", func(msg string) {
	fmt.Printf("Received: %s\n", msg)
})

// Handle disconnection
socket.On("disconnect", func(reason string) {
	fmt.Printf("Disconnected: %s\n", reason)
})
Example (Auth)

ExampleSocket_auth demonstrates how to use authentication with Socket.IO

package main

import (
	"fmt"
	"log"

	client "github.com/winking324/socket.io/clients/socket/v3"
	server "github.com/winking324/socket.io/servers/socket/v3"
	"github.com/winking324/socket.io/v3/pkg/types"
)

func main() {
	config := server.DefaultServerOptions()
	config.SetTransports(types.NewSet(server.Polling, server.WebSocket, server.WebTransport))

	httpServer := types.NewWebServer(nil)

	// Create server with authentication middleware
	io := server.NewServer(httpServer, config)

	// Add authentication middleware
	io.Use(func(socket *server.Socket, next func(*server.ExtendedError)) {
		// Get auth data from handshake
		auth := socket.Handshake().Auth

		// Check if token exists and is valid
		if token, ok := auth["Token"]; ok {
			if tokenStr, ok := token.(string); ok && tokenStr == "test" {
				fmt.Printf("Authentication successful for token: %s\n", tokenStr)
				next(nil) // Authentication passed
				return
			}
		}

		// Authentication failed
		fmt.Println("Authentication failed - invalid or missing token")
		next(server.NewExtendedError("Authentication failed", map[string]any{
			"type": "authentication_error",
		}))
	})

	// Handle successful connections
	io.On("connection", func(clients ...any) {
		socket := clients[0].(*server.Socket)
		fmt.Printf("Client connected\n")

		socket.On("secure-message", func(args ...any) {
			if len(args) > 0 {
				if msg, ok := args[0].(string); ok {
					fmt.Printf("Received secure message: %s\n", msg)
					socket.Emit("secure-reply", "Message received securely")
				}
			}
		})

		socket.On("disconnect", func(args ...any) {
			fmt.Printf("Client disconnected\n")
		})
	})

	done := make(chan struct{})

	httpServer.Listen("127.0.0.1:8000", func() {
		// Client connection with authentication
		opts := client.DefaultOptions()
		opts.SetTransports(types.NewSet(client.Polling, client.WebSocket))
		opts.SetAuth(map[string]any{"Token": "test"})

		socket, err := client.Connect("http://127.0.0.1:8000/", opts)
		if err != nil {
			log.Fatal(err)
		}

		socket.On("connect", func(...any) {
			fmt.Println("Client connected successfully!")
			socket.Emit("secure-message", "Hello from authenticated client!")
		})

		socket.On("secure-reply", func(args ...any) {
			if len(args) > 0 {
				if msg, ok := args[0].(string); ok {
					fmt.Printf("Server reply: %s\n", msg)
				}
			}
			defer socket.Close()
			close(done)
		})

		socket.On("connect_error", func(args ...any) {
			if len(args) > 0 {
				fmt.Printf("Connection error: %v\n", args[0])
			}
			defer socket.Close()
			close(done)
		})
	})

	<-done
	httpServer.Close(nil)

}
Output:
Authentication successful for token: test
Client connected
Client connected successfully!
Received secure message: Hello from authenticated client!
Server reply: Message received securely
Client disconnected
Example (AuthFailed)

ExampleSocket_authFailed demonstrates authentication failure

package main

import (
	"fmt"
	"log"

	client "github.com/winking324/socket.io/clients/socket/v3"
	server "github.com/winking324/socket.io/servers/socket/v3"
	"github.com/winking324/socket.io/v3/pkg/types"
)

func main() {
	config := server.DefaultServerOptions()
	config.SetTransports(types.NewSet(server.Polling, server.WebSocket, server.WebTransport))

	httpServer := types.NewWebServer(nil)

	// Create server with authentication middleware
	io := server.NewServer(httpServer, config)

	// Add authentication middleware
	io.Use(func(socket *server.Socket, next func(*server.ExtendedError)) {
		// Get auth data from handshake
		auth := socket.Handshake().Auth

		// Check if token exists and is valid
		if token, ok := auth["Token"]; ok {
			if tokenStr, ok := token.(string); ok && tokenStr == "valid-token" {
				fmt.Printf("Authentication successful for token: %s\n", tokenStr)
				next(nil) // Authentication passed
				return
			}
		}

		// Authentication failed
		fmt.Println("Authentication failed - invalid or missing token")
		next(server.NewExtendedError("Authentication failed", map[string]any{
			"type": "authentication_error",
		}))
	})

	// Handle successful connections (won't be reached in this example)
	io.On("connection", func(clients ...any) {
		socket := clients[0].(*server.Socket)
		fmt.Printf("Client connected with ID: %s\n", socket.Id())
	})

	done := make(chan struct{})

	httpServer.Listen("127.0.0.1:8000", func() {
		// Client connection with invalid authentication
		opts := client.DefaultOptions()
		opts.SetTransports(types.NewSet(client.Polling, client.WebSocket))
		opts.SetAuth(map[string]any{"Token": "invalid-token"}) // Wrong token

		socket, err := client.Connect("http://127.0.0.1:8000/", opts)
		if err != nil {
			log.Fatal(err)
		}

		socket.On("connect", func(...any) {
			fmt.Println("This shouldn't be called due to auth failure")
		})

		socket.On("connect_error", func(args ...any) {
			fmt.Printf("Authentication failed as expected: %v\n", args[0])
			defer socket.Close()
			close(done)
		})
	})

	<-done
	httpServer.Close(nil)

}
Output:
Authentication failed - invalid or missing token
Authentication failed as expected: Authentication failed
Example (AuthWithUserInfo)

ExampleSocket_authWithUserInfo demonstrates authentication with user information

package main

import (
	"fmt"
	"log"

	client "github.com/winking324/socket.io/clients/socket/v3"
	server "github.com/winking324/socket.io/servers/socket/v3"
	"github.com/winking324/socket.io/v3/pkg/types"
)

func main() {
	config := server.DefaultServerOptions()
	config.SetTransports(types.NewSet(server.Polling, server.WebSocket, server.WebTransport))

	httpServer := types.NewWebServer(nil)

	// Create server with authentication middleware
	io := server.NewServer(httpServer, config)

	// Add authentication middleware with user info extraction
	io.Use(func(socket *server.Socket, next func(*server.ExtendedError)) {
		auth := socket.Handshake().Auth

		// Validate token and extract user info
		if token, ok := auth["Token"]; ok {
			if tokenStr, ok := token.(string); ok && tokenStr == "user123" {
				// Store user info in socket data
				socket.SetData(map[string]string{
					"userId":   "123",
					"username": "testuser",
				})

				fmt.Printf("User authenticated: %s (ID: %s)\n", "testuser", "123")
				next(nil)
				return
			}
		}

		fmt.Println("Authentication failed")
		next(server.NewExtendedError("Invalid credentials", nil))
	})

	// Handle successful connections
	io.On("connection", func(clients ...any) {
		socket := clients[0].(*server.Socket)

		// Access user data
		userId, _ := socket.Data().(map[string]string)["userId"]
		username, _ := socket.Data().(map[string]string)["username"]

		fmt.Printf("Welcome %s! (User ID: %s)\n",
			username, userId)

		socket.On("user-action", func(args ...any) {
			if len(args) > 0 {
				if action, ok := args[0].(string); ok {
					fmt.Printf("User %s performed action: %s\n", username, action)
				}
			}
			socket.Emit("logout")
		})

		socket.Emit("ready")
	})

	done := make(chan struct{})

	httpServer.Listen("127.0.0.1:8000", func() {
		// Client connection with user token
		opts := client.DefaultOptions()
		opts.SetTransports(types.NewSet(client.Polling, client.WebSocket))
		opts.SetAuth(map[string]any{
			"Token": "user123",
		})

		socket, err := client.Connect("http://127.0.0.1:8000/", opts)
		if err != nil {
			log.Fatal(err)
		}

		socket.On("ready", func(...any) {
			socket.Emit("user-action", "login")
		})

		socket.On("logout", func(...any) {
			defer socket.Close()
			close(done)
		})

		socket.On("connect", func(...any) {
			fmt.Println("Connected with user authentication!")
		})

		socket.On("connect_error", func(args ...any) {
			fmt.Printf("Connection error: %v\n", args[0])
			defer socket.Close()
			close(done)
		})
	})

	<-done
	httpServer.Close(nil)

}
Output:
User authenticated: testuser (ID: 123)
Welcome testuser! (User ID: 123)
Connected with user authentication!
User testuser performed action: login
Example (Basic)

ExampleSocket_basic demonstrates the basic usage of Socket.IO client

package main

import (
	"fmt"
	"log"

	client "github.com/winking324/socket.io/clients/socket/v3"
	server "github.com/winking324/socket.io/servers/socket/v3"
	"github.com/winking324/socket.io/v3/pkg/types"
)

func main() {
	config := server.DefaultServerOptions()
	config.SetTransports(types.NewSet(server.Polling, server.WebSocket, server.WebTransport))

	httpServer := types.NewWebServer(nil)
	server.NewServer(httpServer, config)

	done := make(chan struct{})

	httpServer.Listen("127.0.0.1:8000", func() {
		opts := client.DefaultOptions()
		opts.SetTransports(types.NewSet(client.Polling, client.WebSocket))
		socket, err := client.Connect("http://127.0.0.1:8000/", opts)
		if err != nil {
			log.Fatal(err)
		}

		socket.On("connect", func(...any) {
			socket.Emit("message", "Hello server!")
			fmt.Println("Connected!")
			defer socket.Close()
			close(done)
		})

		socket.On("reply", func(args ...any) {
			if len(args) > 0 {
				if msg, ok := args[0].(string); ok {
					fmt.Printf("Received: %s\n", msg)
				}
			}
		})
	})

	<-done
	httpServer.Close(nil)

}
Output:
Connected!
Example (Disconnect)

ExampleSocket_disconnect demonstrates how to disconnect the socket

package main

import (
	"fmt"
	"log"

	client "github.com/winking324/socket.io/clients/socket/v3"
	server "github.com/winking324/socket.io/servers/socket/v3"
	"github.com/winking324/socket.io/v3/pkg/types"
)

func main() {
	config := server.DefaultServerOptions()
	config.SetTransports(types.NewSet(server.Polling, server.WebSocket, server.WebTransport))

	httpServer := types.NewWebServer(nil)
	server.NewServer(httpServer, config)

	done := make(chan struct{})

	httpServer.Listen("127.0.0.1:8000", func() {
		opts := client.DefaultOptions()
		opts.SetTransports(types.NewSet(client.Polling, client.WebSocket))
		socket, err := client.Connect("http://127.0.0.1:8000/", opts)
		if err != nil {
			log.Fatal(err)
		}

		socket.On("connect", func(...any) {
			fmt.Println("Connected!")
			socket.Disconnect()
		})

		socket.On("disconnect", func(args ...any) {
			if len(args) > 0 {
				if reason, ok := args[0].(string); ok {
					fmt.Printf("Disconnected: %s\n", reason)
					defer socket.Close()
					close(done)
				}
			}
		})

	})

	<-done
	httpServer.Close(nil)

}
Output:
Connected!
Disconnected: io client disconnect
Example (EmitWithAck)

ExampleSocket_emitWithAck demonstrates how to emit events with acknowledgement

package main

import (
	"fmt"
	"log"

	client "github.com/winking324/socket.io/clients/socket/v3"
	server "github.com/winking324/socket.io/servers/socket/v3"
	"github.com/winking324/socket.io/v3/pkg/types"
)

func main() {
	config := server.DefaultServerOptions()
	config.SetTransports(types.NewSet(server.Polling, server.WebSocket, server.WebTransport))

	httpServer := types.NewWebServer(nil)
	server.NewServer(httpServer, config).On("connection", func(clients ...any) {
		socket := clients[0].(*server.Socket)
		socket.On("custom-event", func(args ...any) {
			if len(args) > 0 {
				ack, ok := args[len(args)-1].(server.Ack)
				if ok {
					ack(args[:len(args)-1], nil)
				}
			}
		})
	})

	done := make(chan struct{})

	httpServer.Listen("127.0.0.1:8000", func() {
		opts := client.DefaultOptions()
		opts.SetTransports(types.NewSet(client.Polling, client.WebSocket))
		socket, err := client.Connect("http://127.0.0.1:8000/", opts)
		if err != nil {
			log.Fatal(err)
		}

		socket.EmitWithAck("custom-event", "received hello")(func(args []any, err error) {
			if err != nil {
				fmt.Println("Failed to receive ack")
			} else {
				fmt.Printf("Server acknowledged with: %v\n", args)
			}
			defer socket.Close()
			close(done)
		})
	})

	<-done
	httpServer.Close(nil)

}
Output:
Server acknowledged with: [received hello]
Example (OnAny)

ExampleSocket_onAny demonstrates how to listen to all events

package main

import (
	"fmt"
	"log"

	client "github.com/winking324/socket.io/clients/socket/v3"
	server "github.com/winking324/socket.io/servers/socket/v3"
	"github.com/winking324/socket.io/v3/pkg/types"
)

func main() {
	config := server.DefaultServerOptions()
	config.SetTransports(types.NewSet(server.Polling, server.WebSocket, server.WebTransport))

	httpServer := types.NewWebServer(nil)
	server.NewServer(httpServer, config).On("connection", func(clients ...any) {
		socket := clients[0].(*server.Socket)
		socket.On("test-event", func(args ...any) {
			socket.Emit("test-event")
		})
	})

	done := make(chan struct{})

	httpServer.Listen("127.0.0.1:8000", func() {
		opts := client.DefaultOptions()
		opts.SetTransports(types.NewSet(client.Polling, client.WebSocket))
		socket, err := client.Connect("http://127.0.0.1:8000/", opts)
		if err != nil {
			log.Fatal(err)
		}

		socket.OnAny(func(args ...any) {
			fmt.Printf("Caught event: %v\n", args[0])
			defer socket.Close()
			close(done)
		})

		socket.Emit("test-event", "data")
	})

	<-done
	httpServer.Close(nil)

}
Output:
Caught event: test-event
Example (Timeout)

ExampleSocket_timeout demonstrates how to set timeout for acknowledgements

package main

import (
	"fmt"
	"log"
	"time"

	client "github.com/winking324/socket.io/clients/socket/v3"
	server "github.com/winking324/socket.io/servers/socket/v3"
	"github.com/winking324/socket.io/v3/pkg/types"
)

func main() {
	config := server.DefaultServerOptions()
	config.SetTransports(types.NewSet(server.Polling, server.WebSocket, server.WebTransport))

	httpServer := types.NewWebServer(nil)
	server.NewServer(httpServer, config)

	done := make(chan struct{})

	httpServer.Listen("127.0.0.1:8000", func() {
		opts := client.DefaultOptions()
		opts.SetTransports(types.NewSet(client.Polling, client.WebSocket))
		socket, err := client.Connect("http://127.0.0.1:8000/", opts)
		if err != nil {
			log.Fatal(err)
		}

		socket.Timeout(5*time.Second).EmitWithAck("delayed-event", "data")(func(args []any, err error) {
			if err != nil {
				fmt.Println("Event timed out")
			} else {
				fmt.Printf("Received response: %v\n", args)
			}
			defer socket.Close()
			close(done)
		})
	})

	<-done
	httpServer.Close(nil)

}
Output:
Event timed out
Example (Volatile)

ExampleSocket_volatile demonstrates how to send messages that may be lost

package main

import (
	"log"

	client "github.com/winking324/socket.io/clients/socket/v3"
	server "github.com/winking324/socket.io/servers/socket/v3"
	"github.com/winking324/socket.io/v3/pkg/types"
)

func main() {
	config := server.DefaultServerOptions()
	config.SetTransports(types.NewSet(server.Polling, server.WebSocket, server.WebTransport))

	httpServer := types.NewWebServer(nil)
	server.NewServer(httpServer, config)

	done := make(chan struct{})

	httpServer.Listen("127.0.0.1:8000", func() {
		opts := client.DefaultOptions()
		opts.SetTransports(types.NewSet(client.Polling))
		socket, err := client.Connect("http://127.0.0.1:8000/", opts)
		if err != nil {
			log.Fatal(err)
		}

		socket.On("connect", func(...any) {
			// The server may or may not receive this message
			socket.Volatile().Emit("hello", "world")
			defer socket.Close()
			close(done)
		})
	})

	<-done
	httpServer.Close(nil)
}

func Connect

func Connect(uri string, opts OptionsInterface) (*Socket, error)

Connect returns a Socket instance for the given URI and options. It is the main entry point for establishing a new connection.

func Io

func Io(uri string, opts OptionsInterface) (*Socket, error)

Io returns a Socket instance for the given URI and options. It is an alias for Connect.

func MakeSocket

func MakeSocket() *Socket

MakeSocket creates a new Socket instance with default buffers and event listeners.

func NewSocket

func NewSocket(io *Manager, nsp string, opts SocketOptionsInterface) *Socket

NewSocket creates a new Socket instance for the given manager, namespace, and options.

func (*Socket) Active

func (s *Socket) Active() bool

Active checks whether the Socket will try to reconnect when its Manager connects or reconnects.

Example:

socket := io.NewClient("", nil)
fmt.Println(socket.Active()) // true

socket.On("disconnect", func(reason ...any) {
  if slices.TryGetAny[string](reason, 0) == "io server disconnect" {
    // the disconnection was initiated by the server, you need to manually reconnect
    fmt.Println(socket.Active()) // false
  }
  // else the socket will automatically try to reconnect
  fmt.Println(socket.Active()) // true
})

func (*Socket) Auth

func (s *Socket) Auth() map[string]any

Auth returns the authentication credentials for namespace access.

func (*Socket) Close

func (s *Socket) Close() *Socket

Alias for Socket.Disconnect.

func (*Socket) Compress

func (s *Socket) Compress(compress bool) *Socket

Compress sets the compress flag.

Example:

socket := io.NewClient("", nil)
socket.Compress(false).Emit("hello")

compress: If `true`, compresses the sending data.

func (*Socket) Connect

func (s *Socket) Connect() *Socket

Connect "opens" the socket.

Example:

socket := io.NewClient("", nil)
socket.SetAutoConnect(false)
socket.Connect()

func (*Socket) Connected

func (s *Socket) Connected() bool

Connected reports whether the socket is currently connected to the server.

func (*Socket) Construct

func (s *Socket) Construct(io *Manager, nsp string, opts SocketOptionsInterface)

Construct initializes the Socket instance.

io: The Manager instance. nsp: The namespace. opts: The socket options.

func (*Socket) Disconnect

func (s *Socket) Disconnect() *Socket

Disconnect disconnects the socket manually. In that case, the socket will not try to reconnect.

If this is the last active Socket instance of the Manager, the low-level connection will be closed.

Example:

socket := io.NewClient("", nil)
socket.On("disconnect", func(reason ...any) {
  fmt.Println(reason[0]) // prints "io client disconnect"
})

socket.Disconnect()

func (*Socket) Disconnected

func (s *Socket) Disconnected() bool

Disconnected checks whether the socket is currently disconnected.

Example:

socket := io.NewClient("", nil)
socket.On("connect", func(...any) {
  fmt.Println(socket.Disconnected()) // false
})

socket.On("disconnect", func(...any) {
  fmt.Println(socket.Disconnected()) // true
})

func (*Socket) Emit

func (s *Socket) Emit(ev string, args ...any) error

Emit overrides the default emit behavior. If the event is in `events`, it's emitted normally.

Example:

socket := io.NewClient("", nil)
socket.Emit("hello", "world")

// all serializable datastructures are supported (no need to call JSON.stringify)
socket.Emit("hello", 1, "2", map[int][]string{3: {"4"}, 5: {"6"}})

// with an acknowledgement from the server

socket.Emit("hello", "world", func(val []any, err error) {
  // ...
})

func (*Socket) EmitWithAck

func (s *Socket) EmitWithAck(ev string, args ...any) func(socket.Ack)

EmitWithAck emits an event and waits for an acknowledgement.

Example:

// without timeout
socket.EmitWithAck("hello", "world")(func([]any, error){

})

// with a specific timeout
socket.Timeout(1000 * time.Millisecond).EmitWithAck("hello", "world")(func([]any, error){

})

func (*Socket) Id

func (s *Socket) Id() string

Id returns the session identifier for this socket, only available when connected.

func (*Socket) Io

func (s *Socket) Io() *Manager

Io returns the Manager instance that created this Socket.

func (*Socket) ListenersAny

func (s *Socket) ListenersAny() []types.EventListener

ListenersAny returns an array of listeners that are listening for any event that is specified. This array can be manipulated, e.g. to remove listeners.

func (*Socket) ListenersAnyOutgoing

func (s *Socket) ListenersAnyOutgoing() []types.EventListener

ListenersAnyOutgoing returns an array of listeners that are listening for any event that is specified. This array can be manipulated, e.g. to remove listeners.

func (*Socket) OffAny

func (s *Socket) OffAny(listener types.EventListener) *Socket

OffAny removes the listener that will be fired when any event is emitted.

Example:

catchAllListener := func(...any) {
  fmt.Println("got event")
}

socket := io.NewClient("", nil)
socket.OnAny(catchAllListener)

// remove a specific listener
socket.OffAny(catchAllListener)

// or remove all listeners
socket.OffAny()

func (*Socket) OffAnyOutgoing

func (s *Socket) OffAnyOutgoing(listener types.EventListener) *Socket

OffAnyOutgoing removes the listener that will be fired when any event is emitted.

Example:

catchAllListener := func(...any) {
  fmt.Println("sent event")
}

socket := io.NewClient("", nil)
socket.OnAnyOutgoing(catchAllListener)

// remove a specific listener
socket.OffAnyOutgoing(catchAllListener)

// or remove all listeners
socket.OffAnyOutgoing()

func (*Socket) OnAny

func (s *Socket) OnAny(listener types.EventListener) *Socket

OnAny adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the callback.

Example:

socket := io.NewClient("", nil)
socket.OnAny(func(...any) {
  fmt.Println("got event")
})

func (*Socket) OnAnyOutgoing

func (s *Socket) OnAnyOutgoing(listener types.EventListener) *Socket

OnAnyOutgoing adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the callback.

Note: acknowledgements sent to the server are not included.

Example:

socket := io.NewClient("", nil)
socket.OnAnyOutgoing(func(...any) {
  fmt.Println("sent event")
})

func (*Socket) Open

func (s *Socket) Open() *Socket

Open is an alias for Connect.

func (*Socket) PrependAny

func (s *Socket) PrependAny(listener types.EventListener) *Socket

PrependAny adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the callback. The listener is added to the beginning of the listeners array.

Example:

socket := io.NewClient("", nil)
socket.PrependAny(func(...any) {
  fmt.Println("got event")
})

func (*Socket) PrependAnyOutgoing

func (s *Socket) PrependAnyOutgoing(listener types.EventListener) *Socket

PrependAnyOutgoing adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the callback. The listener is added to the beginning of the listeners array.

Note: acknowledgements sent to the server are not included.

Example:

socket := io.NewClient("", nil)
socket.PrependAnyOutgoing(func(...any) {
  fmt.Println("sent event")
})

func (*Socket) ReceiveBuffer

func (s *Socket) ReceiveBuffer() *types.Slice[[]any]

ReceiveBuffer returns the buffer of packets received before the CONNECT packet.

func (*Socket) Recovered

func (s *Socket) Recovered() bool

Recovered reports if the connection state was recovered after reconnection.

func (*Socket) Send

func (s *Socket) Send(args ...any) *Socket

Send sends a `message` event.

This method mimics the WebSocket.send() method.

Example:

socket := io.NewClient("", nil)
socket.Send("hello")

// this is equivalent to
socket.Emit("message", "hello")

func (*Socket) SendBuffer

func (s *Socket) SendBuffer() *types.Slice[*Packet]

SendBuffer returns the buffer of packets to be sent after connection is established.

func (*Socket) Timeout

func (s *Socket) Timeout(timeout time.Duration) *Socket

Timeout sets a modifier for a subsequent event emission that the callback will be called with an error when the given number of milliseconds have elapsed without an acknowledgement from the server:

Example:

socket := io.NewClient("", nil)
socket.Timeout(5000 * time.Millisecond).Emit("my-event", func([]any, err) {
  if err != nil {
    // the server did not acknowledge the event in the given delay
  }
})

func (*Socket) Volatile

func (s *Socket) Volatile() *Socket

Volatile sets a modifier for a subsequent event emission that the event message will be dropped when this socket is not ready to send messages.

Example:

socket := io.NewClient("", nil)
socket.Volatile().Emit("hello") // the server may or may not receive it

type SocketOptions

type SocketOptions struct {
	// contains filtered or unexported fields
}

SocketOptions defines configuration options for individual Socket.IO sockets. These options control the behavior of a specific namespace connection.

func DefaultSocketOptions

func DefaultSocketOptions() *SocketOptions

DefaultSocketOptions creates a new SocketOptions instance with default values. Use this function to create a base configuration that can be customized.

func (*SocketOptions) AckTimeout

func (s *SocketOptions) AckTimeout() time.Duration

func (*SocketOptions) Assign

Assign copies all options from another SocketOptionsInterface instance. If data is nil, it returns the current SocketOptions instance.

func (*SocketOptions) Auth

func (s *SocketOptions) Auth() map[string]any

func (*SocketOptions) GetRawAckTimeout

func (s *SocketOptions) GetRawAckTimeout() types.Optional[time.Duration]

func (*SocketOptions) GetRawAuth

func (s *SocketOptions) GetRawAuth() types.Optional[map[string]any]

func (*SocketOptions) GetRawRetries

func (s *SocketOptions) GetRawRetries() types.Optional[float64]

func (*SocketOptions) Retries

func (s *SocketOptions) Retries() float64

func (*SocketOptions) SetAckTimeout

func (s *SocketOptions) SetAckTimeout(ackTimeout time.Duration)

SetAckTimeout sets how long to wait for an acknowledgement before timing out.

Parameters:

  • d: The timeout duration

func (*SocketOptions) SetAuth

func (s *SocketOptions) SetAuth(auth map[string]any)

SetAuth configures the authentication data to be sent with the connection.

Parameters:

  • auth: A map containing authentication credentials or tokens

func (*SocketOptions) SetRetries

func (s *SocketOptions) SetRetries(retries float64)

SetRetries sets the maximum number of retries for packet delivery

Parameters:

  • retries: The maximum number of retries

type SocketOptionsInterface

type SocketOptionsInterface interface {
	SetAuth(map[string]any)
	GetRawAuth() types.Optional[map[string]any]
	Auth() map[string]any

	SetRetries(float64)
	GetRawRetries() types.Optional[float64]
	Retries() float64

	SetAckTimeout(time.Duration)
	GetRawAckTimeout() types.Optional[time.Duration]
	AckTimeout() time.Duration
}

SocketOptionsInterface defines the interface for accessing and modifying Socket options. It provides methods for authentication, retry logic, and acknowledgement timeouts.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL