socket

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Dec 18, 2025 License: Apache-2.0 Imports: 9 Imported by: 0

README

socket

A simple, high-performance TCP server framework for Go.

Go Reference CI

Features

  • Simple API - Easy to use with functional options pattern
  • Custom Codec - Pluggable message encoding/decoding via io.Reader
  • Graceful Shutdown - Context-based cancellation support
  • Heartbeat - Automatic read/write deadline management
  • Error Handling - Flexible error handling with Disconnect or Continue actions
  • Structured Logging - Built-in slog integration

Requirements

  • Go 1.23+

Installation

go get github.com/Zereker/socket

Quick Start

package main

import (
    "context"
    "io"
    "log"
    "net"

    "github.com/Zereker/socket"
)

// Define your message type
type Message struct {
    Data []byte
}

func (m Message) Length() int  { return len(m.Data) }
func (m Message) Body() []byte { return m.Data }

// Implement the Codec interface
type SimpleCodec struct{}

func (c *SimpleCodec) Decode(r io.Reader) (socket.Message, error) {
    buf := make([]byte, 1024)
    n, err := r.Read(buf)
    if err != nil {
        return nil, err
    }
    return Message{Data: buf[:n]}, nil
}

func (c *SimpleCodec) Encode(msg socket.Message) ([]byte, error) {
    return msg.Body(), nil
}

// Implement the Handler interface
type EchoHandler struct{}

func (h *EchoHandler) Handle(tcpConn *net.TCPConn) {
    conn, err := socket.NewConn(tcpConn,
        socket.CustomCodecOption(&SimpleCodec{}),
        socket.OnMessageOption(func(msg socket.Message) error {
            // Echo the message back
            return conn.Write(msg)
        }),
    )
    if err != nil {
        log.Printf("failed to create connection: %v", err)
        return
    }
    conn.Run(context.Background())
}

func main() {
    addr, _ := net.ResolveTCPAddr("tcp", "127.0.0.1:8080")
    server, err := socket.New(addr)
    if err != nil {
        log.Fatal(err)
    }

    log.Println("server listening on", addr)
    server.Serve(context.Background(), &EchoHandler{})
}

Configuration Options

Option Description Default
CustomCodecOption(codec) Set message codec (required) -
OnMessageOption(handler) Set message handler (required) -
OnErrorOption(handler) Set error handler Disconnect on error
HeartbeatOption(duration) Set heartbeat interval 30s
BufferSizeOption(size) Set send channel buffer size 1
MessageMaxSize(size) Set max message size 1MB
LoggerOption(logger) Set custom logger slog default

Error Handling

Control how errors are handled with OnErrorOption:

socket.OnErrorOption(func(err error) socket.ErrorAction {
    if isTemporaryError(err) {
        return socket.Continue  // Suppress error and continue
    }
    return socket.Disconnect    // Close the connection
})

Write Methods

Three ways to send messages:

// Non-blocking write, returns ErrBufferFull if channel is full
conn.Write(msg)

// Blocking write with context cancellation
conn.WriteBlocking(ctx, msg)

// Write with timeout
conn.WriteTimeout(msg, 5*time.Second)

Custom Logger

Implement the Logger interface or use slog:

type Logger interface {
    Debug(msg string, args ...any)
    Info(msg string, args ...any)
    Warn(msg string, args ...any)
    Error(msg string, args ...any)
}

License

MIT License - see LICENSE for details.

Documentation

Overview

Package socket provides a simple TCP server framework for Go. It supports custom message encoding/decoding, asynchronous I/O operations, and connection management with heartbeat monitoring.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrInvalidCodec is returned when no codec is provided.
	ErrInvalidCodec = errors.New("invalid codec callback")
	// ErrInvalidOnMessage is returned when no message handler is provided.
	ErrInvalidOnMessage = errors.New("invalid on message callback")
)

Errors returned by connection operations.

View Source
var ErrBufferFull = errors.New("send buffer full")

ErrBufferFull is returned when the send buffer is full and cannot accept more messages.

Functions

This section is empty.

Types

type Codec

type Codec interface {
	// Decode reads and decodes a complete message from the reader.
	// The implementation should read exactly the bytes needed for one message.
	// This handles TCP packet fragmentation by allowing the codec to control
	// how many bytes are read.
	Decode(r io.Reader) (Message, error)
	// Encode encodes a Message into raw bytes for transmission.
	Encode(Message) ([]byte, error)
}

Codec is the interface for message encoding and decoding. Applications should implement this interface to define their own message serialization format (e.g., JSON, Protocol Buffers, etc.).

The Decode method reads from an io.Reader, which allows the codec to handle TCP stream reassembly by reading exactly the number of bytes needed for a complete message. This solves the TCP packet fragmentation problem.

type Conn

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

Conn represents a client connection to a TCP server. It manages the underlying TCP connection, message encoding/decoding, and provides read/write loops for asynchronous communication.

func NewConn

func NewConn(conn *net.TCPConn, opt ...Option) (*Conn, error)

NewConn creates a new connection wrapper around the given TCP connection. It applies the provided options and validates them before returning. Returns an error if required options (codec, onMessage) are missing.

func (*Conn) Addr

func (c *Conn) Addr() net.Addr

Addr returns the remote address of the connection.

func (*Conn) Run

func (c *Conn) Run(ctx context.Context) error

Run starts the connection's read and write loops. It creates two goroutines for concurrent reading and writing, and blocks until an error occurs or the context is canceled. The connection is automatically closed when Run returns.

func (*Conn) Write

func (c *Conn) Write(message Message) error

Write sends a message through the connection without blocking. The message is encoded using the configured codec and queued for sending. Returns ErrBufferFull if the send buffer is full.

func (*Conn) WriteBlocking

func (c *Conn) WriteBlocking(ctx context.Context, message Message) error

WriteBlocking sends a message through the connection, blocking until the message is queued or the context is canceled.

func (*Conn) WriteTimeout

func (c *Conn) WriteTimeout(message Message, timeout time.Duration) error

WriteTimeout sends a message through the connection with a timeout. Returns ErrBufferFull if the message cannot be queued within the timeout.

type ErrorAction

type ErrorAction int

ErrorAction defines the action to take when an error occurs.

const (
	// Disconnect closes the connection when an error occurs.
	Disconnect ErrorAction = iota
	// Continue suppresses the error and continues processing.
	Continue
)

type Handler

type Handler interface {
	// Handle is called for each new connection.
	// The implementation is responsible for managing the connection.
	Handle(conn *net.TCPConn)
}

Handler is the interface for handling incoming TCP connections. Implementations should handle the connection lifecycle and message processing.

type Logger

type Logger interface {
	// Debug logs a debug-level message with optional key-value pairs.
	Debug(msg string, args ...any)
	// Info logs an info-level message with optional key-value pairs.
	Info(msg string, args ...any)
	// Warn logs a warning-level message with optional key-value pairs.
	Warn(msg string, args ...any)
	// Error logs an error-level message with optional key-value pairs.
	Error(msg string, args ...any)
}

Logger is the interface for structured logging. It is designed to be compatible with *slog.Logger from the standard library. Applications can provide their own implementation or use the default slog logger.

type Message

type Message interface {
	// Length returns the length of the message body.
	Length() int
	// Body returns the raw message data.
	Body() []byte
}

Message is the interface for messages transmitted over the connection. Implementations should provide the message length and body.

type Option

type Option func(*options)

Option is a function that configures connection options.

func BufferSizeOption

func BufferSizeOption(size int) Option

BufferSizeOption returns an Option that sets the size of the send channel buffer. A larger buffer allows more messages to be queued before blocking.

func CustomCodecOption

func CustomCodecOption(codec Codec) Option

CustomCodecOption returns an Option that sets the message codec. The codec is required and must be provided before creating a connection.

func HeartbeatOption

func HeartbeatOption(heartbeat time.Duration) Option

HeartbeatOption returns an Option that sets the heartbeat interval. This determines the read/write deadline timeout (heartbeat * 2).

func LoggerOption

func LoggerOption(logger Logger) Option

LoggerOption returns an Option that sets the logger. If not set, the default slog logger will be used.

func MessageMaxSize

func MessageMaxSize(size int) Option

MessageMaxSize returns an Option that sets the maximum message buffer size. Messages larger than this size cannot be received.

func OnErrorOption

func OnErrorOption(cb func(error) ErrorAction) Option

OnErrorOption returns an Option that sets the error callback. The callback is invoked when a read/write error occurs. Return Disconnect to close the connection, or Continue to suppress the error.

func OnMessageOption

func OnMessageOption(cb func(Message) error) Option

OnMessageOption returns an Option that sets the message handler callback. This callback is required and is invoked for each received message.

type Server

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

Server represents a TCP server that listens for incoming connections.

func New

func New(addr *net.TCPAddr) (*Server, error)

New creates a new TCP server bound to the specified address. Returns an error if the address cannot be bound.

func (*Server) Addr

func (s *Server) Addr() net.Addr

Addr returns the listener's network address.

func (*Server) Close

func (s *Server) Close() error

Close stops the server by closing the underlying listener. Any blocked Accept calls will return with an error.

func (*Server) Serve

func (s *Server) Serve(ctx context.Context, handler Handler) error

Serve starts accepting connections and dispatching them to the handler. It blocks until the context is canceled or an unrecoverable error occurs. When the context is canceled, it stops accepting new connections gracefully.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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