netpipe

package module
v0.0.0-...-1f60baa Latest Latest
Warning

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

Go to latest
Published: Mar 13, 2026 License: MIT Imports: 15 Imported by: 0

README

NetPipe

A general-purpose TCP/UDP data transport library written in Go.

NetPipe handles the networking complexity so you don't have to. Import the library, call a few functions, and you have a working server or client. Framing, encryption, streaming, reconnection, heartbeats -- all of it is internal. You just send bytes and receive bytes.

Install

go get github.com/ipaz12/NetPipe

Requires Go 1.21 or later. One external dependency: github.com/google/uuid.

Note: The import path uses a capital N to match the GitHub repo name. In your code, you reference the package as netpipe (lowercase) since that is the declared package name.

Quick Start

Server (15 lines):

package main

import (
    "fmt"
    "github.com/ipaz12/NetPipe"
)

func main() {
    server := netpipe.NewServer(netpipe.Config{})

    server.OnConnect(func(id string) {
        fmt.Printf("%s connected (%d online)\n", id[:8], server.ClientCount())
    })

    server.OnData(func(id string, data []byte) {
        fmt.Printf("[%s]: %s", id[:8], string(data))
        server.BroadcastExcept(id, data) // relay to everyone else
    })

    server.Listen()
}

Client (20 lines):

package main

import (
    "bufio"
    "fmt"
    "os"
    "github.com/ipaz12/NetPipe"
)

func main() {
    client := netpipe.NewClient(netpipe.Config{})

    client.OnData(func(data []byte) {
        fmt.Print(string(data))
    })

    client.Connect()

    go client.Listen()

    scanner := bufio.NewScanner(os.Stdin)
    for scanner.Scan() {
        client.Send([]byte(scanner.Text() + "\n"))
    }
}

That's a working chat system. The server relays messages between clients. No framing code, no buffer management, no connection handling. Just Send() and OnData.

Features

Transport: TCP and UDP. Switch protocols with one config change. The rest of the API stays the same.

Message Framing: TCP has no concept of message boundaries. NetPipe adds length-prefix framing so messages always arrive whole, no matter how the network fragments them. You never think about this.

Encryption: AES-256-GCM with SHA-256 key derivation. Send encrypted and unencrypted messages side by side.

client.Send([]byte("public"))
client.SendEncrypted([]byte("private"), "my-secret-key")

The server auto-decrypts if you set EncryptionKey in the config.

Streaming: Large payloads are automatically chunked, sent, and reassembled on the other end. You get the whole thing in one callback.

client.SendStream(bigData) // auto-chunked at 64 KB

server.OnStream(func(id string, data []byte) {
    // data is fully reassembled, could be megabytes
})

Heartbeat: The server pings clients periodically. Clients auto-respond. Dead connections are detected and cleaned up. Zero developer effort.

Auto-Reconnect: The client reconnects automatically with exponential backoff and jitter. Set AutoReconnect: true and forget about it.

Session Resumption: When a client reconnects, the server recognizes it and keeps the same client ID. Your application code sees continuity across disconnections.

Graceful Drain: Stop accepting new connections but let existing clients finish their work.

remaining := server.Drain() // blocks until all clients leave or timeout

Security Hardening: Semaphore-based MaxClients (no race conditions), per-IP connection limits, connect timeout (anti-slowloris), per-client stream limits, deferred cleanup (panic-safe), and rejection frames so clients know why they were dropped.

ATC Dashboard: An optional visual dashboard that shows your server or mesh as a live node graph with animated data transfers. One config flag to enable.

server := netpipe.NewServer(netpipe.Config{
    EnableATC: true, // opens dashboard at http://localhost:5001
})

Peer-to-Peer Mode

NetPipe includes a full P2P mode for direct peer-to-peer communication without a central server. Every connection performs an automatic X25519 Diffie-Hellman key exchange. All traffic is encrypted by default.

peer := netpipe.NewPeer(netpipe.PeerConfig{Port: 6000})

peer.OnData(func(peerID string, data []byte) {
    fmt.Printf("[%s]: %s\n", peerID[:8], string(data))
})

go peer.Listen() // accept incoming peers

peerID, _ := peer.Connect("192.168.1.10", 6000) // connect to another peer
peer.Broadcast([]byte("hello mesh"))

P2P features include full mesh topology, LAN broadcast discovery, partial mesh routing with TTL, and per-connection encryption where each peer pair has its own independent shared secret.

LAN Discovery:

go peer.StartDiscoveryListener() // make this peer discoverable

peer.Discover(func(found []netpipe.PeerInfo) {
    for _, p := range found {
        peer.ConnectTo(p)
    }
})

Routed Messages (partial mesh, not every peer directly connected):

peer.SendRouted(targetPeerID, []byte("reaches target through intermediaries"))

Config Reference

Server Config
Field Type Default Description
Port int 5000 Listening port
Protocol string "tcp" "tcp" or "udp"
EncryptionKey string "" Auto-decrypt incoming encrypted messages
ChunkSize int 65536 Stream chunk size in bytes
MaxStreamsPerClient int 0 Max concurrent incomplete streams per client (0 = unlimited)
MaxClients int 0 Max simultaneous connections (0 = unlimited)
HeartbeatInterval Duration 0 Ping interval (0 = disabled)
HeartbeatTimeout Duration 2x interval Time to wait for pong
IdleTimeout Duration 0 Disconnect idle clients (0 = disabled)
ConnectTimeout Duration 30s Max time before first message
MaxConnsPerIP int 0 Per-IP connection limit (0 = unlimited)
DrainTimeout Duration 30s Max wait for Drain()
EnableATC bool false Enable ATC visual dashboard
ATCPort int Port+1 Dashboard HTTP port
Client Config
Field Type Default Description
Host string "localhost" Server address
Port int 5000 Server port
Protocol string "tcp" "tcp" or "udp"
AutoReconnect bool false Auto-reconnect on disconnect
ReconnectInterval Duration 2s Base interval (doubles with backoff)
MaxReconnectAttempts int 0 Max retries (0 = infinite)
PeerConfig (P2P)
Field Type Default Description
Port int 6000 Listening port
Protocol string "tcp" Protocol
Name string "" Human-readable name for LAN discovery
NoEncrypt bool false Disable DH encryption (testing only)
ChunkSize int 65536 Stream chunk size
EnableATC bool false Enable ATC dashboard
ATCPort int Port+1 Dashboard port

Server API

server := netpipe.NewServer(config)

// Callbacks
server.OnConnect(func(clientID string) { })
server.OnDisconnect(func(clientID string) { })
server.OnData(func(clientID string, data []byte) { })
server.OnStream(func(clientID string, data []byte) { })

// Lifecycle
server.Listen()              // blocks
server.Close()               // shut down
server.Drain()               // graceful shutdown

// Send
server.SendTo(clientID, data)
server.SendToEncrypted(clientID, data, key)
server.Broadcast(data)
server.BroadcastEncrypted(data, key)
server.BroadcastExcept(excludeID, data)
server.BroadcastExceptEncrypted(excludeID, data, key)
server.SendStream(clientID, data)
server.BroadcastStream(data)

// Utility
server.GetClients()          // []string
server.ClientCount()         // int
server.Kick(clientID)        // force disconnect

Client API

client := netpipe.NewClient(config)

// Callbacks
client.OnData(func(data []byte) { })
client.OnDisconnect(func() { })
client.OnStream(func(data []byte) { })
client.OnReject(func(reason string) { })

// Lifecycle
client.Connect()
client.Disconnect()
client.Listen()              // blocks (run in goroutine)
client.IsConnected()

// Send
client.Send(data)
client.SendEncrypted(data, key)
client.SendStream(data)
client.SetEncryptionKey(key) // auto-decrypt incoming

Peer API (P2P)

peer := netpipe.NewPeer(config)

// Callbacks
peer.OnConnect(func(peerID string) { })
peer.OnDisconnect(func(peerID string) { })
peer.OnData(func(peerID string, data []byte) { })
peer.OnStream(func(peerID string, data []byte) { })

// Lifecycle
peer.Listen()                // blocks (run in goroutine)
peer.Connect(host, port)     // returns peerID, error
peer.Close()

// Send
peer.Send(data)              // to first connected peer
peer.SendTo(peerID, data)
peer.Broadcast(data)
peer.SendStream(peerID, data)
peer.BroadcastStream(data)
peer.SendRouted(destID, data) // through intermediaries

// Discovery
peer.Discover(callback)
peer.ConnectTo(peerInfo)
peer.StartDiscoveryListener()

// Utility
peer.GetPeerID()
peer.GetPeers()
peer.PeerCount()
peer.IsConnected()
peer.Disconnect(peerID)
peer.DisconnectAll()

Wire Protocol

See PROTOCOL.md for the full wire protocol specification. Any client in any language that implements the protocol can talk to a NetPipe server. A Python client is available at netpipe-python.

Project Structure

config.go            Config structs and defaults
server.go            TCP server with client registry
client.go            TCP client with auto-reconnect
framing.go           Length-prefix wire protocol
crypto.go            AES-256-GCM encryption
stream.go            Chunked streaming with reassembly
heartbeat.go         Ping/pong, idle timeout, reconnect logic
safeconn.go          Write-mutex connection wrapper
session.go           Session resumption across reconnects
udp.go               UDP server and client
pp.go                P2P peer with DH-encrypted mesh
pp_crypto.go         X25519 key exchange
pp_discovery.go      LAN broadcast discovery
pp_routing.go        Partial mesh message routing
atc_event.go         ATC telemetry event bus
atc_server.go        ATC HTTP/SSE server
atc_hooks.go         ATC integration with Server and Peer
atc_dashboard.go     ATC embedded web dashboard
PROTOCOL.md          Wire protocol specification
cmd/
  server/main.go     Demo chat server
  client/main.go     Demo chat client
  p2p/main.go        Demo P2P mesh chat

Running the Demos

git clone https://github.com/ipaz12/NetPipe
cd NetPipe

# Chat server + clients
go run cmd/server/main.go          # terminal 1
go run cmd/client/main.go          # terminal 2
go run cmd/client/main.go          # terminal 3

# P2P mesh
go run cmd/p2p/main.go -listen -port 6000                     # terminal 1
go run cmd/p2p/main.go -connect 127.0.0.1:6000 -port 6001     # terminal 2
go run cmd/p2p/main.go -connect 127.0.0.1:6000 -port 6002     # terminal 3

Tests

go test ./... -v

22 tests covering framing, encryption, streaming, integration (server/client round-trip, encrypted round-trip, stream reassembly, broadcast, max clients, graceful drain), and P2P mesh.

License

MIT

Documentation

Index

Constants

View Source
const (
	DefaultPort     = 5000
	DefaultProtocol = "tcp"
	DefaultHost     = "localhost"
)
View Source
const (

	// DefaultChunkSize is the default chunk body size (64 KB).
	DefaultChunkSize = 64 * 1024
)
View Source
const (

	// MaxMessageSize caps a single message at 16 MB.
	MaxMessageSize = 16 * 1024 * 1024
)

Variables

This section is empty.

Functions

This section is empty.

Types

type ATCBus

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

ATCBus fans out events to all subscribed dashboard connections.

type ATCEvent

type ATCEvent struct {
	Type      ATCEventType `json:"type"`
	Timestamp int64        `json:"ts"`                  // unix milliseconds
	NodeID    string       `json:"node_id"`             // the client/peer UUID involved
	TargetID  string       `json:"target_id,omitempty"` // for send events: who it's going to
	Bytes     int          `json:"bytes,omitempty"`     // data size
	Message   string       `json:"msg,omitempty"`       // human-readable log line
	Mode      string       `json:"mode"`                // "server", "p2p"
}

ATCEvent is a single telemetry event streamed to the dashboard.

type ATCEventType

type ATCEventType string

ATCEventType identifies what happened.

const (
	ATCEventConnect    ATCEventType = "connect"
	ATCEventDisconnect ATCEventType = "disconnect"
	ATCEventDataSend   ATCEventType = "data_send"
	ATCEventDataRecv   ATCEventType = "data_recv"
	ATCEventStreamSend ATCEventType = "stream_send"
	ATCEventStreamRecv ATCEventType = "stream_recv"
	ATCEventPing       ATCEventType = "ping"
	ATCEventPong       ATCEventType = "pong"
	ATCEventReject     ATCEventType = "reject"
	ATCEventError      ATCEventType = "error"
	ATCEventServerUp   ATCEventType = "server_up"
	ATCEventDrain      ATCEventType = "drain"
	ATCEventSnapshot   ATCEventType = "snapshot" // full state snapshot for new dashboard connections
)

type ATCNode

type ATCNode struct {
	ID        string `json:"id"`
	Label     string `json:"label"`     // short display label (first 8 chars of UUID)
	Connected int64  `json:"connected"` // unix ms when connected
	IP        string `json:"ip,omitempty"`
}

ATCNode represents one connected client or peer in the snapshot.

type ATCServer

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

ATCServer is the HTTP server that serves the ATC dashboard and streams telemetry events via Server-Sent Events (SSE). No external dependencies.

Endpoints:

GET /             - serves the ATC dashboard HTML
GET /events       - SSE stream of real-time events
GET /snapshot     - JSON snapshot of current state

type ATCSnapshot

type ATCSnapshot struct {
	Type       ATCEventType `json:"type"`
	Timestamp  int64        `json:"ts"`
	Mode       string       `json:"mode"`
	ServerPort int          `json:"server_port"`
	Protocol   string       `json:"protocol"`
	Nodes      []ATCNode    `json:"nodes"`
	Encrypted  bool         `json:"encrypted"`
	SelfID     string       `json:"self_id,omitempty"` // for P2P - our own peer ID
}

ATCSnapshot is a full state dump sent when a dashboard first connects.

type Client

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

Client connects to a NetPipe server and exchanges raw data. Create one with NewClient(), register callbacks, Connect(), then go Listen().

func NewClient

func NewClient(cfg Config) *Client

NewClient creates a client with the given config. Pass Config{} for all defaults (localhost:5000, TCP).

func (*Client) Connect

func (c *Client) Connect() error

Connect establishes the connection to the server. Works for both TCP and UDP - the protocol is set in Config.

func (*Client) Disconnect

func (c *Client) Disconnect() error

Disconnect closes the connection cleanly.

func (*Client) IsConnected

func (c *Client) IsConnected() bool

IsConnected returns true if the client has an active connection.

func (*Client) Listen

func (c *Client) Listen()

Listen runs a blocking read loop that fires OnData with complete messages. Designed to be run in a goroutine: go client.Listen() When the connection drops, fires OnDisconnect and returns (or auto-reconnects).

func (*Client) OnData

func (c *Client) OnData(fn func(data []byte))

OnData registers a callback fired when data arrives from the server. Data is raw bytes - the developer decides what they mean.

func (*Client) OnDisconnect

func (c *Client) OnDisconnect(fn func())

OnDisconnect registers a callback fired when the server disconnects.

func (*Client) OnReject

func (c *Client) OnReject(fn func(reason string))

OnReject registers a callback fired when the server rejects the connection. Reason is a short string like "server full" or "too many connections from your IP".

func (*Client) OnStream

func (c *Client) OnStream(fn func(data []byte))

OnStream registers a callback fired when a chunked stream transfer completes. Data is the fully reassembled payload.

func (*Client) Send

func (c *Client) Send(data []byte) error

Send writes raw bytes to the server. Returns an error if not connected. The message is framed automatically so it arrives as a complete unit.

func (*Client) SendEncrypted

func (c *Client) SendEncrypted(data []byte, key string) error

SendEncrypted writes AES-256-GCM encrypted bytes to the server. The key can be any string - it is hashed to 32 bytes internally.

func (*Client) SendStream

func (c *Client) SendStream(data []byte) error

SendStream sends large data as a chunked stream. The server receives it as a single complete payload via OnStream.

func (*Client) SetEncryptionKey

func (c *Client) SetEncryptionKey(key string)

SetEncryptionKey sets the key used to auto-decrypt incoming encrypted messages. Call before Listen().

type Config

type Config struct {
	Host          string // client only - defaults to "localhost"
	Port          int    // defaults to 5000
	Protocol      string // defaults to "tcp" (also supports "udp")
	EncryptionKey string // optional - server uses this to auto-decrypt incoming encrypted messages

	// Stage 6 - Streaming
	ChunkSize           int // stream chunk size in bytes (default 64 KB)
	MaxStreamsPerClient int // server only - 0 = unlimited. max concurrent incomplete streams per client

	// Stage 7 - Robustness
	MaxClients           int           // server only - 0 = unlimited
	HeartbeatInterval    time.Duration // server only - 0 = disabled. e.g. 10 * time.Second
	HeartbeatTimeout     time.Duration // server only - 0 = 2x interval. time to wait for pong before disconnect
	IdleTimeout          time.Duration // server only - 0 = disabled. disconnect clients with no data activity
	ConnectTimeout       time.Duration // server only - 0 = 30s default. max time a new client can sit before sending data
	MaxConnsPerIP        int           // server only - 0 = unlimited. max simultaneous connections from one IP
	DrainTimeout         time.Duration // server only - 0 = 30s default. max wait time for Drain() to complete
	AutoReconnect        bool          // client only - auto-reconnect on disconnect
	MaxReconnectAttempts int           // client only - 0 = infinite retries
	ReconnectInterval    time.Duration // client only - defaults to 2s (base for exponential backoff)

	// Addons
	EnableATC bool // enable the ATC visual dashboard addon. defaults to false
	ATCPort   int  // ATC dashboard HTTP port. defaults to 5001
}

Config controls server or client behaviour. Every field has a sensible default - pass Config{} and it works out of the box.

type Peer

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

Peer is a P2P node that connects directly to other peers without a central server.

Every connection performs an automatic Diffie-Hellman key exchange - all traffic is AES-256-GCM encrypted by default. The developer never handles keys.

In a mesh, each peer maintains its own registry of connected peers. Any peer can send to any other peer it is directly connected to.

Usage:

peer := netpipe.NewPeer(netpipe.PeerConfig{Port: 6000})
peer.OnData(func(peerID string, data []byte) { ... })
go peer.Listen()          // accept incoming connections
peer.Connect("192.168.1.10", 6000)  // connect to another peer
peer.Broadcast([]byte("hello mesh"))

func NewPeer

func NewPeer(cfg PeerConfig) *Peer

NewPeer creates a P2P peer node.

peer := netpipe.NewPeer(netpipe.PeerConfig{Port: 6000})

func (*Peer) Broadcast

func (p *Peer) Broadcast(data []byte)

Broadcast sends data to all connected peers.

func (*Peer) BroadcastStream

func (p *Peer) BroadcastStream(data []byte)

BroadcastStream sends large data to all connected peers as a chunked stream.

func (*Peer) Close

func (p *Peer) Close() error

Close shuts down the listener and disconnects all peers.

func (*Peer) Connect

func (p *Peer) Connect(host string, port int) (string, error)

Connect initiates a direct connection to another peer by address. Performs the DH handshake and adds the peer to the mesh.

func (*Peer) ConnectTo

func (p *Peer) ConnectTo(info PeerInfo) (string, error)

ConnectTo connects to a peer discovered via Discover().

func (*Peer) Disconnect

func (p *Peer) Disconnect(peerID string) error

Disconnect cleanly disconnects one specific peer.

func (*Peer) DisconnectAll

func (p *Peer) DisconnectAll()

DisconnectAll disconnects from every peer in the mesh.

func (*Peer) Discover

func (p *Peer) Discover(callback func([]PeerInfo)) error

Discover broadcasts a discovery request on the local network and collects responses from other NetPipe PP peers. Blocks for up to timeout seconds, then calls the callback with all discovered peers.

peer.Discover(func(found []netpipe.PeerInfo) {
    for _, p := range found {
        peer.ConnectTo(p)
    }
})

func (*Peer) DiscoverWithTimeout

func (p *Peer) DiscoverWithTimeout(callback func([]PeerInfo), timeout time.Duration) error

DiscoverWithTimeout is like Discover but with a custom timeout.

func (*Peer) GetPeerID

func (p *Peer) GetPeerID() string

GetPeerID returns this peer's UUID in the mesh.

func (*Peer) GetPeers

func (p *Peer) GetPeers() []string

GetPeers returns a slice of all connected peer UUIDs.

func (*Peer) IsConnected

func (p *Peer) IsConnected() bool

IsConnected returns true if there is at least one connected peer.

func (*Peer) Listen

func (p *Peer) Listen() error

Listen starts accepting incoming peer connections. Blocks forever. Run in a goroutine: go peer.Listen()

func (*Peer) OnConnect

func (p *Peer) OnConnect(fn func(peerID string))

OnConnect registers a callback fired when a peer joins the mesh.

func (*Peer) OnData

func (p *Peer) OnData(fn func(peerID string, data []byte))

OnData registers a callback fired when data arrives from any peer.

func (*Peer) OnDisconnect

func (p *Peer) OnDisconnect(fn func(peerID string))

OnDisconnect registers a callback fired when a peer leaves the mesh.

func (*Peer) OnStream

func (p *Peer) OnStream(fn func(peerID string, data []byte))

OnStream registers a callback fired when a chunked stream completes from any peer.

func (*Peer) PeerCount

func (p *Peer) PeerCount() int

PeerCount returns the number of connected peers.

func (*Peer) Send

func (p *Peer) Send(data []byte) error

Send sends data to a single directly-connected peer (for 1:1 connections). If multiple peers are connected, use SendTo or Broadcast.

func (*Peer) SendRouted

func (p *Peer) SendRouted(destID string, data []byte) error

SendRouted sends data to a peer that may not be directly connected. The message is forwarded through intermediate peers using the route table. TTL limits the maximum number of hops (default 5).

func (*Peer) SendRoutedTTL

func (p *Peer) SendRoutedTTL(destID string, data []byte, ttl int) error

SendRoutedTTL sends a routed message with a custom TTL.

func (*Peer) SendStream

func (p *Peer) SendStream(peerID string, data []byte) error

SendStream sends large data to a specific peer as a chunked stream.

func (*Peer) SendTo

func (p *Peer) SendTo(peerID string, data []byte) error

SendTo sends data to one specific peer by UUID.

func (*Peer) StartDiscoveryListener

func (p *Peer) StartDiscoveryListener() error

StartDiscoveryListener runs a background goroutine that responds to LAN discovery broadcasts from other peers. Call this on peers that want to be discoverable.

go peer.StartDiscoveryListener()

type PeerConfig

type PeerConfig struct {
	Port      int    // listening port - defaults to 6000
	Protocol  string // defaults to "tcp"
	Name      string // optional human-readable name (advertised during LAN discovery)
	NoEncrypt bool   // set to true to disable DH encryption (testing/trusted LAN only)
	ChunkSize int    // stream chunk size - defaults to 64 KB

	// Addons
	EnableATC bool // enable the ATC visual dashboard addon. defaults to false
	ATCPort   int  // ATC dashboard HTTP port. defaults to 6001
}

PeerConfig controls P2P peer behaviour.

type PeerInfo

type PeerInfo struct {
	ID      string `json:"id"`
	Address string `json:"address"`
	Port    int    `json:"port"`
	Name    string `json:"name"`
}

PeerInfo contains what each peer advertises during LAN discovery.

type Server

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

Server manages client connections and routes data between them. Create one with NewServer(), register callbacks, then call Listen().

func NewServer

func NewServer(cfg Config) *Server

NewServer creates a server with the given config. Pass Config{} for all defaults (port 5000, TCP).

func (*Server) Broadcast

func (s *Server) Broadcast(data []byte)

Broadcast sends data to every connected client.

func (*Server) BroadcastEncrypted

func (s *Server) BroadcastEncrypted(data []byte, key string)

BroadcastEncrypted sends AES-256-GCM encrypted data to every connected client.

func (*Server) BroadcastExcept

func (s *Server) BroadcastExcept(excludeID string, data []byte)

BroadcastExcept sends data to every client except the one specified. Useful for relaying a sender's message to all other clients.

func (*Server) BroadcastExceptEncrypted

func (s *Server) BroadcastExceptEncrypted(excludeID string, data []byte, key string)

BroadcastExceptEncrypted sends encrypted data to every client except one.

func (*Server) BroadcastStream

func (s *Server) BroadcastStream(data []byte)

BroadcastStream sends large data to every client as a chunked stream.

func (*Server) ClientCount

func (s *Server) ClientCount() int

ClientCount returns the number of currently connected clients.

func (*Server) Close

func (s *Server) Close() error

Close shuts down the listener and disconnects all clients.

func (*Server) Drain

func (s *Server) Drain() int

Drain stops accepting new connections but waits for existing clients to finish and disconnect gracefully. Blocks until all clients are gone or DrainTimeout expires (default 30s). Returns the number of clients that were still connected when the timeout hit.

func (*Server) GetClients

func (s *Server) GetClients() []string

GetClients returns a slice of all connected client UUIDs.

func (*Server) Kick

func (s *Server) Kick(clientID string) error

Kick forcibly disconnects a specific client. For TCP: closes the connection, triggering the normal OnDisconnect path. For UDP: removes the client from the registry and fires OnDisconnect.

func (*Server) Listen

func (s *Server) Listen() error

Listen starts accepting client connections. Blocks forever. Works for both TCP and UDP - the protocol is set in Config.

func (*Server) OnConnect

func (s *Server) OnConnect(fn func(clientID string))

OnConnect registers a callback fired when a client connects. The clientID is the client's UUID.

func (*Server) OnData

func (s *Server) OnData(fn func(clientID string, data []byte))

OnData registers a callback fired when a client sends data. Data is raw bytes - the developer decides what they mean.

func (*Server) OnDisconnect

func (s *Server) OnDisconnect(fn func(clientID string))

OnDisconnect registers a callback fired when a client disconnects. The client has already been removed from the registry at this point.

func (*Server) OnStream

func (s *Server) OnStream(fn func(clientID string, data []byte))

OnStream registers a callback fired when a chunked stream transfer completes. Data is the fully reassembled payload - the developer never sees individual chunks.

func (*Server) SendStream

func (s *Server) SendStream(clientID string, data []byte) error

SendStream sends large data to a specific client as a chunked stream. The client receives it as a single complete payload via OnStream.

func (*Server) SendTo

func (s *Server) SendTo(clientID string, data []byte) error

SendTo sends data to one specific client by UUID.

func (*Server) SendToEncrypted

func (s *Server) SendToEncrypted(clientID string, data []byte, key string) error

SendToEncrypted sends AES-256-GCM encrypted data to one specific client.

Directories

Path Synopsis
cmd
client command
p2p command
server command

Jump to

Keyboard shortcuts

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