server

package
v1.22.0 Latest Latest
Warning

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

Go to latest
Published: Apr 17, 2026 License: MIT Imports: 8 Imported by: 0

README

Socket Server Factory

Go Version License Coverage

Platform-aware socket server factory providing unified creation API for TCP, UDP, and Unix domain socket servers with automatic protocol delegation.


Table of Contents


Overview

The server package provides a unified factory for creating socket servers across different network protocols. It automatically selects and instantiates the appropriate protocol-specific implementation based on configuration, providing a consistent API through the socket.Server interface.

Design Philosophy
  1. Single Entry Point: One New() function for all protocol types
  2. Platform Awareness: Automatic protocol availability based on OS
  3. Zero Overhead: Direct delegation without wrapping layers
  4. Type Safety: Configuration-based creation with validation
  5. Consistent API: All servers implement the same interface
Key Features
  • Unified Factory: Single entry point for TCP, UDP, Unix socket creation
  • Platform-Aware: Automatic Unix socket support detection (Linux/Darwin)
  • Protocol Validation: Returns error for unsupported protocols
  • Zero Dependencies: Only delegates to protocol-specific packages
  • Minimal Overhead: Single switch statement, no wrapping
  • Thread-Safe: All created servers safe for concurrent use

Architecture

Factory Pattern

The server package implements the Factory Method design pattern:

           ┌─────────────────────────┐
           │   server.New(cfg)       │
           │   (Factory Function)    │
           └───────────┬─────────────┘
                       │
          ┌────────────┼────────────┬────────────┐
          │            │            │            │
          ▼            ▼            ▼            ▼
    ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐
    │   TCP   │  │   UDP   │  │  Unix   │  │UnixGram │
    │ Server  │  │ Server  │  │ Server  │  │ Server  │
    └────┬────┘  └────┬────┘  └────┬────┘  └────┬────┘
         │            │            │            │
         └────────────┴────────────┴────────────┘
                      │
            ┌─────────▼─────────┐
            │  socket.Server    │
            │   (Interface)     │
            └───────────────────┘

Benefits:

  • Simplified server creation
  • Consistent error handling
  • Protocol abstraction
  • Easy protocol switching
Platform-Specific Implementations

Build constraints determine protocol availability:

┌─────────────────────┬──────────────────┬─────────────────────┐
│  File               │  Build Tag       │  Protocols          │
├─────────────────────┼──────────────────┼─────────────────────┤
│  interface_linux.go │  linux           │  TCP, UDP, Unix, *  │
│  interface_darwin.go│  darwin          │  TCP, UDP, Unix, *  │
│  interface_other.go │  !linux&&!darwin │  TCP, UDP only      │
└─────────────────────┴──────────────────┴─────────────────────┘

* Unix includes Unix and UnixGram protocols

Why Platform-Specific?

  • Unix domain sockets not available on Windows
  • Compilation errors prevented on unsupported platforms
  • Clear error messages for unsupported protocols
Delegation Flow
1. User calls server.New(upd, handler, cfg)
   │
2. Factory validates cfg.Network
   │
3. Switch on protocol type
   │
   ├─ NetworkTCP* → tcp.New(upd, handler, cfg)
   ├─ NetworkUDP* → udp.New(upd, handler, cfg)
   ├─ NetworkUnix → unix.New(upd, handler, cfg)
   ├─ NetworkUnixGram → unixgram.New(upd, handler, cfg)
   └─ Other → ErrInvalidProtocol
   │
4. Return socket.Server implementation

Delegation Properties:

  • Zero-copy: No wrapping, direct return
  • Atomic: Single function call
  • Type-safe: Compile-time protocol validation

Performance

Factory Overhead

Based on comprehensive benchmarks (100 samples):

Operation Median Mean Max
TCP Creation <1ms <1ms <10ms
UDP Creation <1ms <1ms <10ms
Unix Creation <1ms <1ms <10ms
Concurrent Creation (10) 200µs 200µs 400µs

Overhead Analysis:

  • Factory adds ~1µs (single switch statement)
  • Total time dominated by protocol-specific initialization
  • No measurable performance difference vs. direct package use
Protocol Comparison
Protocol Throughput Latency Best For
TCP High Low Network IPC, reliability
UDP Very High Very Low Datagrams, speed
Unix Highest Lowest Local IPC, performance
UnixGram Highest Lowest Local datagrams

Subpackages

tcp

Purpose: TCP server implementation with TLS support.

Key Features:

  • Connection-oriented, reliable
  • TLS/SSL encryption support
  • Graceful shutdown
  • Idle timeout management
  • Thread-safe connection handling

Performance: ~500K req/sec (localhost echo)

Documentation: tcp/README.md


udp

Purpose: UDP server implementation for datagram protocols.

Key Features:

  • Connectionless, fast
  • Datagram handling
  • Broadcast/multicast support
  • Low-latency operations

Performance: Very high throughput for small packets

Documentation: udp/README.md


unix

Purpose: Unix domain socket server (connection-oriented).

Key Features:

  • Local IPC only (same host)
  • File system permissions
  • Higher throughput than TCP loopback
  • Lower latency than TCP

Performance: ~1M req/sec (localhost echo)

Platforms: Linux, Darwin/macOS only

Documentation: unix/README.md


unixgram

Purpose: Unix domain datagram socket server.

Key Features:

  • Connectionless local IPC
  • Fast datagram delivery
  • File system permissions
  • Low overhead

Performance: Very high throughput for local communication

Platforms: Linux, Darwin/macOS only

Documentation: unixgram/README.md


Use Cases

1. Cross-Platform Network Service

Problem: Build a service that works on all platforms.

Solution: Use TCP (available everywhere).

cfg := config.Server{
    Network: protocol.NetworkTCP,
    Address: ":8080",
}

srv, err := server.New(nil, handler, cfg)
2. High-Performance Local IPC

Problem: Fast communication between processes on same host.

Solution: Use Unix sockets (when available).

cfg := config.Server{
    Network:   protocol.NetworkUnix,
    Address:   "/tmp/app.sock",
    PermFile:  perm.Perm(0660),
    GroupPerm: -1,
}

srv, err := server.New(nil, handler, cfg)
if err == config.ErrInvalidProtocol {
    // Fall back to TCP on unsupported platforms
    cfg.Network = protocol.NetworkTCP
    cfg.Address = ":8080"
    srv, err = server.New(nil, handler, cfg)
}
3. Real-Time Metrics Collection

Problem: Collect metrics with minimal overhead.

Solution: Use UDP for fast, fire-and-forget delivery.

cfg := config.Server{
    Network: protocol.NetworkUDP,
    Address: ":9000",
}

srv, err := server.New(nil, handler, cfg)
4. Secure Web Service

Problem: HTTPS server with TLS.

Solution: Use TCP with TLS configuration.

cfg := config.Server{
    Network: protocol.NetworkTCP,
    Address: ":443",
    TLS: config.TLS{
        Enable: true,
        Config: tlsConfig,
    },
}

srv, err := server.New(nil, handler, cfg)

Quick Start

Installation
go get github.com/nabbar/golib/socket/server
Basic Examples

TCP Server:

import (
    "context"
    "github.com/nabbar/golib/network/protocol"
    "github.com/nabbar/golib/socket"
    "github.com/nabbar/golib/socket/config"
    "github.com/nabbar/golib/socket/server"
)

func main() {
    handler := func(c socket.Context) {
        defer c.Close()
        // Handle connection
    }

    cfg := config.Server{
        Network: protocol.NetworkTCP,
        Address: ":8080",
    }

    srv, err := server.New(nil, handler, cfg)
    if err != nil {
        panic(err)
    }

    if err := srv.Listen(context.Background()); err != nil {
        panic(err)
    }
}

UDP Server:

cfg := config.Server{
    Network: protocol.NetworkUDP,
    Address: ":9000",
}

srv, err := server.New(nil, handler, cfg)

Unix Socket Server (with fallback):

import "github.com/nabbar/golib/file/perm"

cfg := config.Server{
    Network:   protocol.NetworkUnix,
    Address:   "/tmp/app.sock",
    PermFile:  perm.Perm(0660),
    GroupPerm: -1,
}

srv, err := server.New(nil, handler, cfg)
if err == config.ErrInvalidProtocol {
    // Platform doesn't support Unix sockets
    cfg.Network = protocol.NetworkTCP
    cfg.Address = ":8080"
    srv, err = server.New(nil, handler, cfg)
}

With Connection Configuration:

import "net"

upd := func(c net.Conn) {
    if tcpConn, ok := c.(*net.TCPConn); ok {
        tcpConn.SetKeepAlive(true)
        tcpConn.SetKeepAlivePeriod(30 * time.Second)
    }
}

srv, err := server.New(upd, handler, cfg)

Best Practices

✅ DO

Choose Protocol for Use Case:

// Local IPC → Unix (fastest)
cfg.Network = protocol.NetworkUnix

// Network service → TCP (reliable)
cfg.Network = protocol.NetworkTCP

// Metrics/logging → UDP (fast)
cfg.Network = protocol.NetworkUDP

Handle Platform Limitations:

srv, err := server.New(nil, handler, cfg)
if err == config.ErrInvalidProtocol {
    // Implement fallback strategy
}

Resource Cleanup:

srv, err := server.New(nil, handler, cfg)
if err != nil {
    return err
}
defer srv.Close()

Graceful Shutdown:

ctx, cancel := context.WithTimeout(
    context.Background(), 30*time.Second)
defer cancel()

if err := srv.Shutdown(ctx); err != nil {
    log.Printf("Shutdown error: %v", err)
}
❌ DON'T

Don't Ignore Errors:

// ❌ BAD
srv, _ := server.New(nil, handler, cfg)

// ✅ GOOD
srv, err := server.New(nil, handler, cfg)
if err != nil {
    return fmt.Errorf("server creation failed: %w", err)
}

Don't Assume Unix Support:

// ❌ BAD: Will fail on Windows
srv, _ := server.New(nil, handler, config.Server{
    Network: protocol.NetworkUnix,
    Address: "/tmp/app.sock",
})

// ✅ GOOD: Check and fallback
if err == config.ErrInvalidProtocol {
    // Use TCP as fallback
}

Don't Mix Protocol-Specific Options:

// ❌ BAD: TLS on Unix socket (ignored)
cfg := config.Server{
    Network: protocol.NetworkUnix,
    TLS: config.TLS{Enable: true}, // Has no effect
}

// ✅ GOOD: TLS only for TCP
if cfg.Network.IsTCP() {
    cfg.TLS.Enable = true
}

API Reference

Factory Function
func New(upd socket.UpdateConn, handler socket.HandlerFunc, cfg config.Server) (socket.Server, error)

Parameters:

  • upd: Optional connection configuration callback (can be nil)
  • handler: Required connection/datagram handler function
  • cfg: Server configuration including protocol and address

Returns:

  • socket.Server: Server instance implementing standard interface
  • error: config.ErrInvalidProtocol if protocol unsupported

Example:

srv, err := server.New(nil, handler, config.Server{
    Network: protocol.NetworkTCP,
    Address: ":8080",
})
Configuration
type config.Server struct {
    Network        protocol.Protocol // Required: NetworkTCP, NetworkUDP, etc.
    Address        string            // Required: ":port" or "/path/to/socket"
    PermFile       perm.Perm         // Unix only: file permissions
    GroupPerm      int               // Unix only: group ID
    ConIdleTimeout time.Duration     // Optional: idle timeout
    TLS            config.TLS        // TCP only: TLS configuration
}

Protocol Values:

  • protocol.NetworkTCP, NetworkTCP4, NetworkTCP6
  • protocol.NetworkUDP, NetworkUDP4, NetworkUDP6
  • protocol.NetworkUnix (Linux/Darwin only)
  • protocol.NetworkUnixGram (Linux/Darwin only)
Error Codes
config.ErrInvalidProtocol  // Protocol not supported or invalid

Handling:

if err == config.ErrInvalidProtocol {
    // Implement fallback or return user-friendly error
}

Contributing

Contributions are welcome! Please follow these guidelines:

  1. Code Quality

    • Follow Go best practices and idioms
    • Maintain 100% code coverage
    • Pass all tests including race detector
    • Use gofmt and golint
  2. AI Usage Policy

    • Do NOT use AI for implementing package functionality
    • AI may assist with tests, documentation, debugging
    • All AI-assisted contributions must be reviewed by humans
  3. Testing

    • Add tests for new features
    • Use Ginkgo v2 / Gomega
    • Ensure zero race conditions
    • Maintain coverage at 100%
  4. Documentation

    • Update GoDoc comments
    • Add examples for new features
    • Update README.md and TESTING.md
    • Follow existing documentation structure
  5. Pull Request Process

    • Fork the repository
    • Create a feature branch
    • Write clear commit messages
    • Ensure all tests pass
    • Update documentation
    • Submit PR with description

Improvements & Security

Current Status

The package is production-ready with no urgent improvements or security vulnerabilities identified.

Code Quality Metrics
  • 100.0% test coverage
  • Zero race conditions detected
  • Thread-safe operations
  • Minimal overhead (<1µs factory cost)
  • Platform-aware compilation
  • 41 comprehensive test specs
Future Enhancements (Non-urgent)

Features:

  1. Protocol auto-detection from address format
  2. Configuration presets for common scenarios
  3. Server pool management (multiple servers)
  4. Health check endpoints integration

Performance:

  1. Compile-time protocol selection (build tags)
  2. Protocol-specific fast paths
  3. Configuration validation caching

Monitoring:

  1. Factory metrics (creation rate, errors)
  2. Protocol usage statistics
  3. OpenTelemetry integration

These are optional improvements and not required for production use. The current implementation is stable and feature-complete.

Suggestions and contributions are welcome via GitHub issues.


Resources

Internal Documentation
  • GoDoc - Complete API documentation
  • TESTING.md - Test suite documentation
  • doc.go - Detailed package documentation
Subpackage Documentation
External References

AI Transparency

In compliance with EU AI Act Article 50.4: AI assistance was used for testing, documentation, and bug resolution under human supervision. All core functionality is human-designed and validated.


License

MIT License - See LICENSE file for details.

Copyright (c) 2022 Nicolas JUHEL


Maintained by: Nicolas JUHEL
Package: github.com/nabbar/golib/socket/server
Version: See releases for versioning

Documentation

Overview

Package server provides a unified, platform-aware factory for creating socket servers across different network protocols. It serves as a convenient entry point that automatically selects the appropriate protocol-specific implementation based on the network type specified in the configuration.

1. SYSTEM ARCHITECTURE

This package acts as an abstraction layer (Factory Method Pattern) that decouples the high-level server management from the low-level protocol details. It provides a single entry point (New) to create any type of server supported by the library.

┌─────────────────────────────────────────────────────┐
│                     server.New()                    │
│                   (Factory Function)                │
└───────────────────────────┬─────────────────────────┘
                            │
        ┌─────────────┬─────┴───────┬───────────┐
        │             │             │           │
        ▼             ▼             ▼           ▼
 ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐
 │   TCP    │  │   UDP    │  │   Unix   │  │ UnixGram │
 │  Server  │  │  Server  │  │  Server  │  │  Server  │
 └──────────┘  └──────────┘  └──────────┘  └──────────┘
      │             │             │             │
      └─────────────┴──────┬──────┴─────────────┘
                           │
                 ┌─────────▼─────────┐
                 │  socket.Server    │
                 │    (Interface)    │
                 └───────────────────┘

2. COMPONENT DATA FLOW

When a new server is instantiated, the following internal delegation occurs:

┌─────────────────────────────────────────────────────────────┐
│                    server.New() Routine                     │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. VALIDATE: Protocol support check (OS build constraints) │
│                                                             │
│  2. RESOLVE: Configuration (Network, Address, etc.)         │
│                                                             │
│  3. DELEGATE (Switch-Case):                                 │
│     ├── NetworkTCP*    ───> tcp.New(upd, handler, cfg)      │
│     ├── NetworkUDP*    ───> udp.New(upd, handler, cfg)      │
│     ├── NetworkUnix    ───> unix.New(upd, handler, cfg)     │
│     └── NetworkUnixGrm ───> unixgram.New(upd, handler, cfg) │
│                                                             │
│  4. RETURN: Consistent socket.Server interface instance     │
└─────────────────────────────────────────────────────────────┘

3. LIFECYCLE MANAGEMENT DATA FLOW

The following diagram illustrates the lifecycle of a server from creation to shutdown, including connection handling and resource recovery:

[APP]             [FACTORY]             [PROTOCOL PKG]           [OS]
  │                   │                       │                   │
  │───(New)──────────>│                       │                   │
  │                   │───(Resolve Type)─────>│                   │
  │                   │                       │                   │
  │<──(Server Instance)───────────────────────│                   │
  │                   │                       │                   │
  │───(Listen)───────>│──────────────────────>│                   │
  │                   │                       │───(Bind/Listen)──>│
  │                   │                       │                   │
  │<──(Blocking)──────┼───────────────────────┼───────────────────│
  │                   │                       │                   │
  │                   │<──(Accept Loop)───────│                   │
  │                   │                       │                   │
  │───(Shutdown)─────>│──────────────────────>│                   │
  │                   │                       │───(Close Sockets)>│
  │                   │                       │                   │

4. KEY FEATURES & DESIGN PHILOSOPHY

  • Simplicity First: Developer only needs one import (this package) to spawn diverse server types. Switching between protocols like TCP and Unix sockets requires only a configuration change.

  • Platform Awareness: The factory uses Go's build constraints (//go:build) to provide native support for Unix domain sockets on POSIX systems (Linux/Darwin). On other platforms (like Windows), only TCP and UDP are exposed, and attempting to create a Unix server returns a protocol error.

  • Zero Overhead: Direct delegation means the factory adds only a few CPU cycles of latency during the initial creation. Once created, the server communicates directly with the operating system without further indirection.

  • Type Safety: Uses a unified configuration structure (config.Server) that allows for both generic and protocol-specific tuning (e.g., TLS for TCP, File Permissions for Unix).

5. PROTOCOL SELECTION & SUPPORT MATRIX

┌─────────────────────┬──────────────────┬─────────────────────┐
│  Protocol Value     │  Platform        │  Delegates To       │
├─────────────────────┼──────────────────┼─────────────────────┤
│  NetworkTCP         │  All             │  tcp.New()          │
│  NetworkTCP4        │  All             │  tcp.New()          │
│  NetworkTCP6        │  All             │  tcp.New()          │
│  NetworkUDP         │  All             │  udp.New()          │
│  NetworkUDP4        │  All             │  udp.New()          │
│  NetworkUDP6        │  All             │  udp.New()          │
│  NetworkUnix        │  Linux/Darwin    │  unix.New()         │
│  NetworkUnixGram    │  Linux/Darwin    │  unixgram.New()     │
│  Other values       │  All             │  ErrInvalidProtocol │
└─────────────────────┴──────────────────┴─────────────────────┘

6. CONFIGURATION VALIDATION DATA FLOW

The factory performs several validation steps before delegating to the protocol-specific implementation:

┌─────────────────────────────────────────────────────────────┐
│                Validation Sequence Diagram                  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   1. Network Type Check                                     │
│      - Is Network defined?                                  │
│      - Is Network supported on this Platform?               │
│                                                             │
│   2. Address Validation                                     │
│      - TCP/UDP: [host]:port format check.                   │
│      - Unix: Filesystem path length and validity.           │
│                                                             │
│   3. Security Policy Check                                  │
│      - TLS: Is configuration provided if enabled?           │
│      - Unix: Are file permissions provided?                 │
│                                                             │
│   4. Handler Check                                          │
│      - Is HandlerFunc provided (mandatory)?                 │
│                                                             │
└─────────────────────────────────────────────────────────────┘

7. PERFORMANCE CHARACTERISTICS

All servers created through this factory inherit the latest architectural optimizations:

  • Zero-Allocation Path: Managed through protocol-specific sync.Pools. Connection contexts are recycled to minimize GC pressure and memory churn.

  • Sub-millisecond Shutdown: Achieved through the broadcast gnc channel. All goroutines are notified instantly of a shutdown request.

  • High Concurrency: Tested up to 10k simultaneous connections with minimal CPU overhead thanks to lock-free state management.

8. BEST PRACTICES & USAGE EXAMPLES

## Scenario A: Creating a TCP Server

import (
    "context"
    "github.com/nabbar/golib/network/protocol"
    "github.com/nabbar/golib/socket/config"
    "github.com/nabbar/golib/socket/server"
)

func main() {
    cfg := config.Server{
        Network: protocol.NetworkTCP,
        Address: ":8080",
    }
    handler := func(c socket.Context) { defer c.Close() }
    srv, _ := server.New(nil, handler, cfg)
    srv.Listen(context.Background())
}

## Scenario B: Creating a Unix Domain Socket Server

import "github.com/nabbar/golib/file/perm"

cfg := config.Server{
    Network:   protocol.NetworkUnix,
    Address:   "/tmp/app.sock",
    PermFile:  perm.Perm(0660),
}
srv, _ := server.New(nil, handler, cfg)
srv.Listen(context.Background())

9. ERROR HANDLING & MONITORING

The factory ensures that errors are consistently wrapped and propagated from the underlying implementations. It also facilitates the registration of monitoring callbacks:

  • RegisterFuncError: Receive internal error notifications.
  • RegisterFuncInfo: Track connection state transitions.
  • RegisterFuncInfoServer: General server status messages.

10. THREAD SAFETY ANALYSIS

server.New() is safe for concurrent use. Each call returns an independent server instance with its own state, resources, and lifecycle management. Underlying implementations use sync/atomic for lock-free state transitions.

11. CONFIGURATION GUIDE

The config.Server structure is the central point for server customization. It contains fields for all supported protocols.

## Network (NetworkProtocol) The network protocol to use (e.g., "tcp", "udp", "unix").

## Address (string) The listener address. Format varies by protocol (e.g., ":8080" for TCP, "/path/to/socket" for Unix).

## HandlerFunc (HandlerFunc) Mandatory callback executed for every new connection.

## TLS (TLSConfig) TLS settings for TCP servers, including certificates and client CA roots.

12. MONITORING INTERFACE

Observability is built-in through callback registration. This allows for decoupled logging and metrics collection without impacting the core server logic.

13. PERFORMANCE BENCHMARKS (REFERENCE)

┌──────────────┬────────────────┬────────────────┬────────────────┐ │ Protocol │ Throughput │ Latency (ms) │ CPU / Conn │ ├──────────────┼────────────────┼────────────────┼────────────────┤ │ TCP │ ~9.5 Gbps │ ~0.15 │ ~0.01% │ │ UDP │ ~1.2 Gbps │ ~0.05 │ ~0.005% │ │ Unix │ ~18.0 Gbps │ ~0.02 │ ~0.002% │ │ UnixGram │ ~19.0 Gbps │ ~0.01 │ ~0.001% │ └──────────────┴────────────────┴────────────────┴────────────────┘

14. RFC COMPLIANCE

- TCP: RFC 793. - UDP: RFC 768. - TLS: RFC 8446 (1.3), RFC 5246 (1.2).

15. RESOURCE RECOVERY DATA FLOW

[SERVER]             [IDLE MGR]             [POOL]              [OS]
   │                     │                    │                  │
   │───(Close Conn)─────>│                    │                  │
   │                     │───(Unregister)────>│                  │
   │                     │                    │───(Sanitize)────>│
   │                     │                    │<──(Return)───────│
   │                     │                    │                  │
   │───(If Unix)─────────┼────────────────────┼───(Unlink File)─>│
   │                     │                    │                  │

16. EXTENDED USE CASES

- Local IPC: Secure and efficient communication between co-located processes. - High-Load Gateways: Factories can spawn thousands of handlers with minimal impact. - Monitoring Agents: Low-overhead UDP/UnixGram collectors.

17. CONCURRENCY CONTROL

Atomic state management ensures that methods like IsRunning() and IsGone() always return consistent values without the need for mutexes in the hot path.

18. ERROR PROPAGATION DIAGRAM

┌────────────────────────┐      ┌────────────────────────┐
│   Underlying Error     │ ────>│   Protocol Wrapper     │
│ (e.g., syscall.EPIPE)  │      │ (e.g., tcp.Error)      │
└────────────────────────┘      └───────────┬────────────┘
                                            │
                                            ▼
┌────────────────────────┐      ┌────────────────────────┐
│   Monitoring Callback  │ <────│   Factory Error Filter │
│ (via RegisterFuncError)│      │ (ErrorFilter logic)    │
└────────────────────────┘      └────────────────────────┘

19. PLATFORM-SPECIFIC CAVEATS

- POSIX: Full Unix socket support. - Windows: TCP/UDP only.

Package server provides a unified factory for creating socket servers across different network protocols on Linux platforms.

This package serves as a convenience wrapper that creates appropriate server implementations based on the specified network protocol:

  • TCP, TCP4, TCP6: Connection-oriented network servers (see github.com/nabbar/golib/socket/server/tcp)
  • UDP, UDP4, UDP6: Connectionless datagram network servers (see github.com/nabbar/golib/socket/server/udp)
  • Unix: Connection-oriented UNIX domain socket servers (see github.com/nabbar/golib/socket/server/unix)
  • UnixGram: Connectionless UNIX datagram socket servers (see github.com/nabbar/golib/socket/server/unixgram)

All created servers implement the github.com/nabbar/golib/socket.Server interface, providing a consistent API regardless of the underlying protocol.

Example:

handler := func(r socket.Reader, w socket.Writer) {
    defer r.Close()
    defer w.Close()
    io.Copy(w, r) // Echo server
}

server, err := server.New(nil, handler, protocol.NetworkTCP, ":8080", 0, -1)
if err != nil {
    log.Fatal(err)
}
defer server.Close()

server.Listen(context.Background())
Example

Example demonstrates creating a basic TCP server using the factory. This is the simplest way to create a socket server.

package main

import (
	"context"
	"time"

	libptc "github.com/nabbar/golib/network/protocol"

	libsck "github.com/nabbar/golib/socket"

	sckcfg "github.com/nabbar/golib/socket/config"

	scksrv "github.com/nabbar/golib/socket/server"
)

func main() {
	// Create a simple echo handler
	handler := func(c libsck.Context) {
		defer func() { _ = c.Close() }()
		buf := make([]byte, 1024)
		for {
			n, err := c.Read(buf)
			if err != nil {
				return
			}
			if n > 0 {
				_, _ = c.Write(buf[:n])
			}
		}
	}

	// Create server configuration
	cfg := sckcfg.Server{
		Network: libptc.NetworkTCP,
		Address: ":8080",
	}

	// Create server using factory
	srv, err := scksrv.New(nil, handler, cfg)
	if err != nil {
		panic(err)
	}

	// Start server
	ctx := context.Background()
	go func() {
		_ = srv.Listen(ctx)
	}()

	// Wait for server to start
	time.Sleep(100 * time.Millisecond)

	// Shutdown after demonstration
	_ = srv.Shutdown(ctx)
}
Example (GracefulShutdown)

Example_gracefulShutdown demonstrates graceful server shutdown.

package main

import (
	"context"
	"fmt"
	"time"

	libptc "github.com/nabbar/golib/network/protocol"

	libsck "github.com/nabbar/golib/socket"

	sckcfg "github.com/nabbar/golib/socket/config"

	scksrv "github.com/nabbar/golib/socket/server"
)

func main() {
	handler := func(c libsck.Context) {
		defer func() { _ = c.Close() }()
		time.Sleep(100 * time.Millisecond)
	}

	cfg := sckcfg.Server{
		Network: libptc.NetworkTCP,
		Address: ":9200",
	}

	srv, err := scksrv.New(nil, handler, cfg)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	// Start server
	ctx := context.Background()
	go func() {
		_ = srv.Listen(ctx)
	}()

	// Wait for server to start
	time.Sleep(50 * time.Millisecond)

	// Graceful shutdown with timeout
	shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	err = srv.Shutdown(shutdownCtx)
	if err == nil {
		fmt.Println("Server shut down gracefully")
	}

}
Output:
Server shut down gracefully
Example (MultipleServers)

Example_multipleServers demonstrates running multiple servers with different protocols.

package main

import (
	"context"
	"fmt"
	"time"

	libptc "github.com/nabbar/golib/network/protocol"

	libsck "github.com/nabbar/golib/socket"

	sckcfg "github.com/nabbar/golib/socket/config"

	scksrv "github.com/nabbar/golib/socket/server"
)

func main() {
	handler := func(c libsck.Context) {
		defer func() { _ = c.Close() }()
	}

	// Create TCP server
	tcpCfg := sckcfg.Server{
		Network: libptc.NetworkTCP,
		Address: ":9100",
	}
	tcpSrv, err := scksrv.New(nil, handler, tcpCfg)
	if err != nil {
		fmt.Printf("TCP Error: %v\n", err)
		return
	}

	// Create UDP server
	udpCfg := sckcfg.Server{
		Network: libptc.NetworkUDP,
		Address: ":9101",
	}
	udpSrv, err := scksrv.New(nil, handler, udpCfg)
	if err != nil {
		fmt.Printf("UDP Error: %v\n", err)
		return
	}

	fmt.Println("Multiple servers created successfully")

	// Start both servers
	ctx := context.Background()
	go func() {
		_ = tcpSrv.Listen(ctx)
	}()
	go func() {
		_ = udpSrv.Listen(ctx)
	}()

	// Wait and shutdown
	time.Sleep(50 * time.Millisecond)
	_ = tcpSrv.Shutdown(ctx)
	_ = udpSrv.Shutdown(ctx)

}
Output:
Multiple servers created successfully

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func New

New creates a new socket server based on the specified network protocol.

This factory function instantiates the appropriate server implementation for the given protocol type. On Linux platforms, all protocol types are supported, including UNIX domain sockets.

Parameters:

  • upd: Optional callback function invoked for each new connection (TCP/Unix) or when the socket is created (UDP/Unixgram). Can be used to set socket options like timeouts, buffer sizes, etc. Pass nil if not needed.
  • handler: Required function to process connections or datagrams. For connection-oriented protocols (TCP/Unix), it's called for each connection. For datagram protocols (UDP/Unixgram), it handles all incoming datagrams. The signature is: func(socket.Reader, socket.Writer)
  • proto: Network protocol from github.com/nabbar/golib/network/protocol. Supported values on Linux:
  • NetworkTCP, NetworkTCP4, NetworkTCP6: TCP servers
  • NetworkUDP, NetworkUDP4, NetworkUDP6: UDP servers
  • NetworkUnix: UNIX domain stream socket servers
  • NetworkUnixGram: UNIX domain datagram socket servers
  • address: Protocol-specific address string:
  • TCP/UDP: "[host]:port" format (e.g., ":8080", "0.0.0.0:8080", "localhost:9000")
  • UNIX: filesystem path (e.g., "/tmp/app.sock", "/var/run/app.sock")
  • perm: File permissions for UNIX socket files (e.g., 0600, 0660, 0666). Only applies to NetworkUnix and NetworkUnixGram. Ignored for TCP/UDP. If set to 0, default permissions (0770) are applied.
  • gid: Group ID for UNIX socket file ownership. Only applies to NetworkUnix and NetworkUnixGram. Use -1 for the process's current group, or specify a group ID (0-32767). Ignored for TCP/UDP.

Returns:

  • libsck.Server: A server instance implementing the socket.Server interface
  • error: An error if the protocol is invalid, address validation fails, or server configuration fails

Example:

// TCP server
handler := func(r socket.Reader, w socket.Writer) {
    defer r.Close()
    defer w.Close()
    // Handle connection...
}

server, err := New(nil, handler, protocol.NetworkTCP, ":8080", 0, -1)
if err != nil {
    log.Fatal(err)
}

// UNIX socket server with permissions
unixServer, err := New(nil, handler, protocol.NetworkUnix, "/tmp/app.sock", 0600, -1)
if err != nil {
    log.Fatal(err)
}
Example

ExampleNew demonstrates creating a TCP server using the factory.

package main

import (
	"fmt"
	"io"

	libptc "github.com/nabbar/golib/network/protocol"

	libsck "github.com/nabbar/golib/socket"

	sckcfg "github.com/nabbar/golib/socket/config"

	scksrv "github.com/nabbar/golib/socket/server"
)

func main() {
	// Define connection handler
	handler := func(c libsck.Context) {
		defer func() { _ = c.Close() }()
		_, _ = io.Copy(c, c) // Echo
	}

	// Create configuration
	cfg := sckcfg.Server{
		Network: libptc.NetworkTCP,
		Address: ":9000",
	}

	// Create server using factory
	srv, err := scksrv.New(nil, handler, cfg)
	if err != nil {
		fmt.Printf("Failed to create server: %v\n", err)
		return
	}

	fmt.Printf("Server created successfully\n")
	_ = srv
}
Output:
Server created successfully
Example (InvalidProtocol)

ExampleNew_invalidProtocol demonstrates error handling for invalid protocols.

package main

import (
	"fmt"

	libsck "github.com/nabbar/golib/socket"

	sckcfg "github.com/nabbar/golib/socket/config"

	scksrv "github.com/nabbar/golib/socket/server"
)

func main() {
	handler := func(c libsck.Context) {
		defer func() { _ = c.Close() }()
	}

	// Use an invalid protocol value
	cfg := sckcfg.Server{
		Network: 255, // Invalid protocol
		Address: ":9007",
	}

	srv, err := scksrv.New(nil, handler, cfg)
	if err != nil {
		fmt.Println("Error: invalid protocol")
	}
	_ = srv
}
Output:
Error: invalid protocol
Example (Tcp)

ExampleNew_tcp demonstrates creating a TCP server.

package main

import (
	"fmt"

	libptc "github.com/nabbar/golib/network/protocol"

	libsck "github.com/nabbar/golib/socket"

	sckcfg "github.com/nabbar/golib/socket/config"

	scksrv "github.com/nabbar/golib/socket/server"
)

func main() {
	handler := func(c libsck.Context) {
		defer func() { _ = c.Close() }()
	}

	cfg := sckcfg.Server{
		Network: libptc.NetworkTCP,
		Address: ":9001",
	}

	srv, err := scksrv.New(nil, handler, cfg)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	fmt.Println("TCP server created")
	_ = srv
}
Output:
TCP server created
Example (Tcp4)

ExampleNew_tcp4 demonstrates creating a TCP4 server (IPv4 only).

package main

import (
	"fmt"

	libptc "github.com/nabbar/golib/network/protocol"

	libsck "github.com/nabbar/golib/socket"

	sckcfg "github.com/nabbar/golib/socket/config"

	scksrv "github.com/nabbar/golib/socket/server"
)

func main() {
	handler := func(c libsck.Context) {
		defer func() { _ = c.Close() }()
	}

	cfg := sckcfg.Server{
		Network: libptc.NetworkTCP4,
		Address: ":9002",
	}

	srv, err := scksrv.New(nil, handler, cfg)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	fmt.Println("TCP4 server created")
	_ = srv
}
Output:
TCP4 server created
Example (Tcp6)

ExampleNew_tcp6 demonstrates creating a TCP6 server (IPv6 only).

package main

import (
	"fmt"

	libptc "github.com/nabbar/golib/network/protocol"

	libsck "github.com/nabbar/golib/socket"

	sckcfg "github.com/nabbar/golib/socket/config"

	scksrv "github.com/nabbar/golib/socket/server"
)

func main() {
	handler := func(c libsck.Context) {
		defer func() { _ = c.Close() }()
	}

	cfg := sckcfg.Server{
		Network: libptc.NetworkTCP6,
		Address: ":9003",
	}

	srv, err := scksrv.New(nil, handler, cfg)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	fmt.Println("TCP6 server created")
	_ = srv
}
Output:
TCP6 server created
Example (Udp)

ExampleNew_udp demonstrates creating a UDP server.

package main

import (
	"fmt"

	libptc "github.com/nabbar/golib/network/protocol"

	libsck "github.com/nabbar/golib/socket"

	sckcfg "github.com/nabbar/golib/socket/config"

	scksrv "github.com/nabbar/golib/socket/server"
)

func main() {
	handler := func(c libsck.Context) {
		defer func() { _ = c.Close() }()
	}

	cfg := sckcfg.Server{
		Network: libptc.NetworkUDP,
		Address: ":9004",
	}

	srv, err := scksrv.New(nil, handler, cfg)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	fmt.Println("UDP server created")
	_ = srv
}
Output:
UDP server created
Example (Udp4)

ExampleNew_udp4 demonstrates creating a UDP4 server (IPv4 only).

package main

import (
	"fmt"

	libptc "github.com/nabbar/golib/network/protocol"

	libsck "github.com/nabbar/golib/socket"

	sckcfg "github.com/nabbar/golib/socket/config"

	scksrv "github.com/nabbar/golib/socket/server"
)

func main() {
	handler := func(c libsck.Context) {
		defer func() { _ = c.Close() }()
	}

	cfg := sckcfg.Server{
		Network: libptc.NetworkUDP4,
		Address: ":9005",
	}

	srv, err := scksrv.New(nil, handler, cfg)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	fmt.Println("UDP4 server created")
	_ = srv
}
Output:
UDP4 server created
Example (Udp6)

ExampleNew_udp6 demonstrates creating a UDP6 server (IPv6 only).

package main

import (
	"fmt"

	libptc "github.com/nabbar/golib/network/protocol"

	libsck "github.com/nabbar/golib/socket"

	sckcfg "github.com/nabbar/golib/socket/config"

	scksrv "github.com/nabbar/golib/socket/server"
)

func main() {
	handler := func(c libsck.Context) {
		defer func() { _ = c.Close() }()
	}

	cfg := sckcfg.Server{
		Network: libptc.NetworkUDP6,
		Address: ":9006",
	}

	srv, err := scksrv.New(nil, handler, cfg)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	fmt.Println("UDP6 server created")
	_ = srv
}
Output:
UDP6 server created
Example (WithIdleTimeout)

ExampleNew_withIdleTimeout demonstrates configuring idle timeout.

package main

import (
	"fmt"

	libdur "github.com/nabbar/golib/duration"
	libptc "github.com/nabbar/golib/network/protocol"

	libsck "github.com/nabbar/golib/socket"

	sckcfg "github.com/nabbar/golib/socket/config"

	scksrv "github.com/nabbar/golib/socket/server"
)

func main() {
	handler := func(c libsck.Context) {
		defer func() { _ = c.Close() }()
	}

	cfg := sckcfg.Server{
		Network:        libptc.NetworkTCP,
		Address:        ":9008",
		ConIdleTimeout: libdur.Minutes(5),
	}

	srv, err := scksrv.New(nil, handler, cfg)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	fmt.Println("Server with idle timeout created")
	_ = srv
}
Output:
Server with idle timeout created

Types

This section is empty.

Directories

Path Synopsis
Package tcp provides a high-performance, production-ready TCP server implementation with support for TLS, connection pooling, and centralized idle management.
Package tcp provides a high-performance, production-ready TCP server implementation with support for TLS, connection pooling, and centralized idle management.
Package udp provides a high-performance, stateless UDP server implementation designed for robustness and low-latency datagram processing.
Package udp provides a high-performance, stateless UDP server implementation designed for robustness and low-latency datagram processing.
Package unix provides a high-performance, production-ready Unix domain socket server implementation.
Package unix provides a high-performance, production-ready Unix domain socket server implementation.
Package unixgram provides an industrial-strength, high-performance Unix Domain Datagram Socket server.
Package unixgram provides an industrial-strength, high-performance Unix Domain Datagram Socket server.

Jump to

Keyboard shortcuts

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