gnet v2

repository·dev·Indexed 11 days ago

https://github.com/panjf2000/gnet

A high-performance, lightweight, event-driven networking framework for Go. Designed as a non-blocking alternative to the standard 'net' package, gnet uses epoll and kqueue to build performance-critical network services at the transport layer (TCP, UDP, and Unix Domain Sockets). It features a lock-free runtime, a built-in goroutine pool powered by ants, and supports edge-triggered I/O across Linux, macOS, Windows, and *BSD.

Tokens
7.4K
Snippets
31
Records
42
Agent score
94%

What's inside gnet

  1. Supported Protocols and Features

    dev

    Supported Transport Protocols

    • TCP
    • UDP
    • Unix Domain Socket

    Core Features

    • High-performance event-driven looping: Based on a multi-threaded/goroutine networking model.
    • Built-in goroutine pool: Powered by the ants library.
    • Lock-free runtime: Designed for high concurrency without lock contention.
    • Memory Management: Uses efficient, reusable, and elastic buffers (Elastic-Ring-Buffer, Linked-List-Buffer, and Elastic-Mixed-Buffer).
    • Load Balancing: Supports Round-Robin, Source-Addr-Hash, and Least-Connections algorithms.
    • I/O Support: Supports Edge-triggered I/O.
    • Client Support: Includes a built-in gnet client.
    • Platform Support: Runs on Linux, macOS, Windows, and *BSD (Darwin, DragonFlyBSD, FreeBSD, NetBSD, OpenBSD).
  2. Core features of gnet

    dev

    gnet provides several high-performance features for network programming:

    • Event-Driven Loop: High-performance multi-threaded/goroutine network model.
    • Lock-free Lifecycle: The entire lifecycle is designed to be lock-free.
    • Goroutine Pool: Built-in support via the ants library.
    • Memory Management: Efficient, reusable, and auto-scaling buffers (Elastic-Ring-Buffer, Linked-List-Buffer, and Elastic-Mixed-Buffer).
    • Load Balancing: Supports Round-Robin, Source-Addr-Hash, and Least-Connections algorithms.
    • Protocols & IPC: Supports TCP, UDP, and Unix Domain Socket.
    • I/O Model: Supports Edge-triggered I/O.
    • Platform Support: Linux, macOS, Windows, and *BSD (Darwin, DragonFlyBSD, FreeBSD, NetBSD, OpenBSD).

    Note: The Windows version is intended for development and testing only; it should not be used in production environments.

  3. What is gnet and when to use it

    dev

    gnet is a high-performance, lightweight, event-driven networking framework implemented in pure Go. It is built from scratch using epoll and kqueue to provide lower memory consumption and higher performance compared to the standard Go net package.

    Key Characteristics:

    • Non-blocking: Designed for high-concurrency, non-blocking I/O.
    • Transport Layer Focus: It provides core transport layer capabilities (TCP, UDP, and Unix Domain Socket) rather than being an all-in-one application framework.
    • Application Layer Implementation: Developers use gnet to implement their own application-level protocols such as HTTP, RPC, Redis, or WebSocket.
    • Different Paradigm: Unlike the standard net package, gnet follows an event-driven model similar to libuv or netty. It is not a direct replacement for net but an alternative for performance-sensitive services.
  4. What is gnet and how does it differ from Go net?

    dev

    gnet is an ultra-fast, lightweight, event-driven networking framework built from scratch using epoll and kqueue.

    Key Differences:

    • Philosophy: Unlike the standard Go net package, gnet is non-blocking and event-driven. It is designed for performance-critical services where low memory consumption and high throughput are required.
    • Scope: gnet is not a comprehensive replacement for net. It provides a concise set of core APIs for the transport layer (TCP, UDP, and Unix Domain Sockets), allowing developers to implement their own application-layer protocols (like HTTP, RPC, or Redis) on top of it.
    • Model: It uses a multi-threaded/goroutine looping model and is lock-free during runtime.
  5. Install gnet v2

    dev

    To use the current version (v2) of gnet, add it to your Go module using the following command. Ensure you are using Go 1.20 or higher as per the minimum requirements.

    go get -u github.com/panjf2000/gnet/v2
  6. Use the Conn interface to interact with connections

    dev

    The Conn interface is the primary way to interact with an active connection. It embeds Reader, Writer, and Socket interfaces.

    Important Concurrency Rules:

    • Non-thread-safe methods: Reader methods (Next, Peek, Discard, InboundBuffered) and most Writer methods (Write, Writev, Flush) must be called within EventHandler methods (like OnTraffic).
    • Thread-safe methods: Socket methods (Fd, SetReadBuffer, SetKeepAlive, etc.), Close, SetDeadline, and AsyncWrite/AsyncWritev can be called from any goroutine.

    Reading Data (Reader):

    • Next(n int): Returns the next n bytes and advances the buffer.
    • Peek(n int): Returns the next n bytes without advancing the buffer.
    • Discard(n int): Advances the buffer by n bytes.

    Writing Data (Writer):

    • Write(p []byte): Synchronous write (not thread-safe).
    • AsyncWrite(buf []byte, callback AsyncCallback): Asynchronous write (thread-safe).
  7. Implement the EventHandler interface

    dev

    The EventHandler interface defines the lifecycle callbacks for network events. You can implement all methods or embed gnet.BuiltinEventEngine to only implement the ones you need.

    Key methods:

    • OnBoot(eng Engine): Called when the engine is ready.
    • OnOpen(c Conn): Called when a new connection is opened. Returns out []byte to send immediately and an Action (e.g., gnet.Close).
    • OnClose(c Conn, err error): Called when a connection closes.
    • OnTraffic(c Conn): Called when data is received. Use the Conn object to read data.
    • OnTick(): Called periodically based on the duration returned.
    • OnShutdown(eng Engine): Called when the engine shuts down.
  8. Start the gnet engine with Run or Rotate

    dev

    To start a networking server, use gnet.Run for a single address or gnet.Rotate for multiple addresses. You must provide an EventHandler to handle network events.

    Addresses must use a scheme prefix:

    • tcp, tcp4, tcp6 (default is tcp)
    • udp, udp4, udp6
    • unix (Unix Domain Socket)

    Example address format: tcp://127.0.0.1:9851 or unix:///tmp/gnet.sock.

    package main
    
    import "github.com/panjf2000/gnet/v2"
    
    type ec struct {
    	gnet.BuiltinEventEngine
    }
    
    func main() {
    	err := gnet.Run(&ec{}, "tcp://:9851")
    	if err != nil {
    		panic(err)
    	}
    }
  9. Configure gnet using functional options

    dev

    gnet uses a functional options pattern to configure the engine. You can pass multiple Option functions to the engine initialization (typically gnet.New) to customize its behavior. Each option is created using a With... helper function.

    Commonly used options include:

    • WithMulticore(bool): Enables multi-core mode. If true, the number of event loops is automatically assigned to the number of usable logical CPUs.
    • WithNumEventLoop(int): Sets a specific number of event-loop goroutines. A non-negative value here overrides WithMulticore.
    • WithReadBufferCap(int): Sets the maximum bytes read from a remote connection (default 64KB). Values are rounded up to the nearest power of two.
    • WithWriteBufferCap(int): Sets the maximum size for the static outbound buffer (default 64KB). Values are rounded up to the nearest power of two.
    • WithLoadBalancing(LoadBalancing): Selects the load-balancing algorithm for assigning connections to event loops (server-only).
    // Example of configuring gnet with options
    engine, err := gnet.New(application, gnet.WithMulticore(true), gnet.WithNumEventLoop(4), gnet.WithReadBufferCap(128 * 1024))
  10. Initialize a gnet Client

    dev

    Use NewClient to create a new Client instance. You must provide an EventHandler to handle network events and can optionally provide Option arguments to configure the client (e.g., buffer sizes, logging, or TCP settings).

    NewClient(eh EventHandler, opts ...Option) (*Client, error)

    // Example initialization
    cli, err := gnet.NewClient(myEventHandler, gnet.WithReadBufferCap(1024))
    if err != nil {
    	panic(err)
    }