gnet

package module
v1.3.0 Latest Latest
Warning

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

Go to latest
Published: Sep 13, 2020 License: MIT Imports: 23 Imported by: 103

README

gnet



English | 🇨🇳中文

📖 Introduction

gnet is an event-driven networking framework that is fast and lightweight. It makes direct epoll and kqueue syscalls rather than using the standard Go net package and works in a similar manner as netty and libuv, which makes gnet achieve a much higher performance than Go net.

gnet is not designed to displace the standard Go net package, but to create a networking server framework for Go that performs on par with Redis and Haproxy for networking packets handling.

gnet sells itself as a high-performance, lightweight, non-blocking, event-driven networking framework written in pure Go which works on transport layer with TCP/UDP protocols and Unix Domain Socket , so it allows developers to implement their own protocols(HTTP, RPC, WebSocket, Redis, etc.) of application layer upon gnet for building diversified network applications, for instance, you get an HTTP Server or Web Framework if you implement HTTP protocol upon gnet while you have a Redis Server done with the implementation of Redis protocol upon gnet and so on.

gnet derives from the project: evio while having a much higher performance and more features.

🚀 Features

  • High-performance event-loop under networking model of multiple threads/goroutines
  • Built-in goroutine pool powered by the library ants
  • Built-in memory pool with bytes powered by the library bytebufferpool
  • Lock-free during the entire runtime
  • Concise and easy-to-use APIs
  • Efficient and reusable memory buffer: Ring-Buffer
  • Supporting multiple protocols/IPC mechanism: TCP, UDP and Unix Domain Socket
  • Supporting multiple load-balancing algorithms: Round-Robin, Source-Addr-Hash and Least-Connections
  • Supporting two event-driven mechanisms: epoll on Linux and kqueue on FreeBSD/DragonFly/Darwin
  • Supporting asynchronous write operation
  • Flexible ticker event
  • SO_REUSEPORT socket option
  • Built-in multiple codecs to encode/decode network frames into/from TCP stream: LineBasedFrameCodec, DelimiterBasedFrameCodec, FixedLengthFrameCodec and LengthFieldBasedFrameCodec, referencing netty codec, also supporting customized codecs
  • Supporting Windows platform with event-driven mechanism of IOCP Go stdlib: net
  • Implementation of gnet Client

📊 Performance

Benchmarks on TechEmpower

# Hardware Environment
CPU: 28 HT Cores Intel(R) Xeon(R) Gold 5120 CPU @ 2.20GHz
Mem: 32GB RAM
OS : Ubuntu 18.04.3 4.15.0-88-generic #88-Ubuntu
Net: Switched 10-gigabit ethernet
Go : go1.14.x linux/amd64

All language

This is the top 50 on the framework ranking of all programming languages consists of a total of 422 frameworks from all over the world where gnet is the runner-up.

Golang

This is the full framework ranking of Go and gnet tops all the other frameworks, which makes gnet the fastest networking framework in Go.

To see the full ranking list, visit TechEmpower Plaintext Benchmark.

Contrasts to the similar networking libraries

On Linux (epoll)

Test Environment
# Machine information
        OS : Ubuntu 18.04/x86_64
       CPU : 8 Virtual CPUs
    Memory : 16.0 GiB

# Go version and configurations
Go Version : go1.12.9 linux/amd64
GOMAXPROCS=8
Echo Server

HTTP Server

On FreeBSD (kqueue)

Test Environment
# Machine information
        OS : macOS Mojave 10.14.6/x86_64
       CPU : 4 CPUs
    Memory : 8.0 GiB

# Go version and configurations
Go Version : go version go1.12.9 darwin/amd64
GOMAXPROCS=4
Echo Server

HTTP Server

🏛 Website

Please visit the official website for more details about architecture, usage and other information of gnet.

⚠️ License

Source code in gnet is available under the MIT License.

👏 Contributors

Please read the Contributing Guidelines before opening a PR and thank you to all the developers who already made contributions to gnet!

⚓ Relevant Articles

🎡 User cases

Please feel free to add your projects here~~

🔋 JetBrains OS licenses

gnet had been being developed with GoLand IDE under the free JetBrains Open Source license(s) granted by JetBrains s.r.o., hence I would like to express my thanks here.

💰 Backers

Support us with a monthly donation and help us continue our activities.

💎 Sponsors

Become a bronze sponsor with a monthly donation of $10 and get your logo on our README on Github.

☕️ Buy me a coffee

Please be sure to leave your name, Github account or other social media accounts when you donate by the following means so that I can add it to the list of donors as a token of my appreciation.

        

Donors

Patrick Othmer Jimmy ChenZhen Mai Yang 王开帅

Documentation

Index

Constants

This section is empty.

Variables

View Source
var CRLFByte = byte('\n')

CRLFByte represents a byte of CRLF.

Functions

func Serve

func Serve(eventHandler EventHandler, protoAddr string, opts ...Option) (err error)

Serve starts handling events for the specified address.

Address should use a scheme prefix and be formatted like `tcp://192.168.0.10:9851` or `unix://socket`. Valid network schemes:

tcp   - bind to both IPv4 and IPv6
tcp4  - IPv4
tcp6  - IPv6
udp   - bind to both IPv4 and IPv6
udp4  - IPv4
udp6  - IPv6
unix  - Unix Domain Socket

The "tcp" network scheme is assumed when one is not specified.

Types

type Action

type Action int

Action is an action that occurs after the completion of an event.

const (
	// None indicates that no action should occur following an event.
	None Action = iota

	// Close closes the connection.
	Close

	// Shutdown shutdowns the server.
	Shutdown
)

type BuiltInFrameCodec added in v1.0.0

type BuiltInFrameCodec struct {
}

BuiltInFrameCodec is the built-in codec which will be assigned to gnet server when customized codec is not set up.

func (*BuiltInFrameCodec) Decode added in v1.0.0

func (cc *BuiltInFrameCodec) Decode(c Conn) ([]byte, error)

Decode ...

func (*BuiltInFrameCodec) Encode added in v1.0.0

func (cc *BuiltInFrameCodec) Encode(c Conn, buf []byte) ([]byte, error)

Encode ...

type Conn

type Conn interface {
	// Context returns a user-defined context.
	Context() (ctx interface{})

	// SetContext sets a user-defined context.
	SetContext(ctx interface{})

	// LocalAddr is the connection's local socket address.
	LocalAddr() (addr net.Addr)

	// RemoteAddr is the connection's remote peer address.
	RemoteAddr() (addr net.Addr)

	// Read reads all data from inbound ring-buffer and event-loop-buffer without moving "read" pointer, which means
	// it does not evict the data from buffers actually and those data will present in buffers until the
	// ResetBuffer method is called.
	Read() (buf []byte)

	// ResetBuffer resets the buffers, which means all data in inbound ring-buffer and event-loop-buffer will be evicted.
	ResetBuffer()

	// ReadN reads bytes with the given length from inbound ring-buffer and event-loop-buffer without moving
	// "read" pointer, which means it will not evict the data from buffers until the ShiftN method is called,
	// it reads data from the inbound ring-buffer and event-loop-buffer and returns both bytes and the size of it.
	// If the length of the available data is less than the given "n", ReadN will return all available data, so you
	// should make use of the variable "size" returned by it to be aware of the exact length of the returned data.
	ReadN(n int) (size int, buf []byte)

	// ShiftN shifts "read" pointer in the internal buffers with the given length.
	ShiftN(n int) (size int)

	// BufferLength returns the length of available data in the internal buffers.
	BufferLength() (size int)

	// SendTo writes data for UDP sockets, it allows you to send data back to UDP socket in individual goroutines.
	SendTo(buf []byte) error

	// AsyncWrite writes data to client/connection asynchronously, usually you would call it in individual goroutines
	// instead of the event-loop goroutines.
	AsyncWrite(buf []byte) error

	// Wake triggers a React event for this connection.
	Wake() error

	// Close closes the current connection.
	Close() error
}

Conn is a interface of gnet connection.

type DecoderConfig added in v1.0.0

type DecoderConfig struct {
	// ByteOrder is the ByteOrder of the length field.
	ByteOrder binary.ByteOrder
	// LengthFieldOffset is the offset of the length field
	LengthFieldOffset int
	// LengthFieldLength is the length of the length field
	LengthFieldLength int
	// LengthAdjustment is the compensation value to add to the value of the length field
	LengthAdjustment int
	// InitialBytesToStrip is the number of first bytes to strip out from the decoded frame
	InitialBytesToStrip int
}

DecoderConfig config for decoder.

type DelimiterBasedFrameCodec added in v1.0.0

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

DelimiterBasedFrameCodec encodes/decodes specific-delimiter-separated frames into/from TCP stream.

func NewDelimiterBasedFrameCodec added in v1.0.0

func NewDelimiterBasedFrameCodec(delimiter byte) *DelimiterBasedFrameCodec

NewDelimiterBasedFrameCodec instantiates and returns a codec with a specific delimiter.

func (*DelimiterBasedFrameCodec) Decode added in v1.0.0

func (cc *DelimiterBasedFrameCodec) Decode(c Conn) ([]byte, error)

Decode ...

func (*DelimiterBasedFrameCodec) Encode added in v1.0.0

func (cc *DelimiterBasedFrameCodec) Encode(c Conn, buf []byte) ([]byte, error)

Encode ...

type EncoderConfig added in v1.0.0

type EncoderConfig struct {
	// ByteOrder is the ByteOrder of the length field.
	ByteOrder binary.ByteOrder
	// LengthFieldLength is the length of the length field.
	LengthFieldLength int
	// LengthAdjustment is the compensation value to add to the value of the length field
	LengthAdjustment int
	// LengthIncludesLengthFieldLength is true, the length of the prepended length field is added to the value of
	// the prepended length field
	LengthIncludesLengthFieldLength bool
}

EncoderConfig config for encoder.

type EventHandler added in v1.0.0

type EventHandler interface {
	// OnInitComplete fires when the server is ready for accepting connections.
	// The parameter:server has information and various utilities.
	OnInitComplete(server Server) (action Action)

	// OnShutdown fires when the server is being shut down, it is called right after
	// all event-loops and connections are closed.
	OnShutdown(server Server)

	// OnOpened fires when a new connection has been opened.
	// The parameter:c has information about the connection such as it's local and remote address.
	// Parameter:out is the return value which is going to be sent back to the client.
	OnOpened(c Conn) (out []byte, action Action)

	// OnClosed fires when a connection has been closed.
	// The parameter:err is the last known connection error.
	OnClosed(c Conn, err error) (action Action)

	// PreWrite fires just before any data is written to any client socket, this event function is usually used to
	// put some code of logging/counting/reporting or any prepositive operations before writing data to client.
	PreWrite()

	// React fires when a connection sends the server data.
	// Call c.Read() or c.ReadN(n) within the parameter:c to read incoming data from client.
	// Parameter:out is the return value which is going to be sent back to the client.
	React(frame []byte, c Conn) (out []byte, action Action)

	// Tick fires immediately after the server starts and will fire again
	// following the duration specified by the delay return value.
	Tick() (delay time.Duration, action Action)
}

EventHandler represents the server events' callbacks for the Serve call. Each event has an Action return value that is used manage the state of the connection and server.

type EventServer added in v1.0.0

type EventServer struct {
}

EventServer is a built-in implementation of EventHandler which sets up each method with a default implementation, you can compose it with your own implementation of EventHandler when you don't want to implement all methods in EventHandler.

func (*EventServer) OnClosed added in v1.0.0

func (es *EventServer) OnClosed(c Conn, err error) (action Action)

OnClosed fires when a connection has been closed. The parameter:err is the last known connection error.

func (*EventServer) OnInitComplete added in v1.0.0

func (es *EventServer) OnInitComplete(svr Server) (action Action)

OnInitComplete fires when the server is ready for accepting connections. The parameter:server has information and various utilities.

func (*EventServer) OnOpened added in v1.0.0

func (es *EventServer) OnOpened(c Conn) (out []byte, action Action)

OnOpened fires when a new connection has been opened. The parameter:c has information about the connection such as it's local and remote address. Parameter:out is the return value which is going to be sent back to the client.

func (*EventServer) OnShutdown added in v1.2.0

func (es *EventServer) OnShutdown(svr Server)

OnShutdown fires when the server is being shut down, it is called right after all event-loops and connections are closed.

func (*EventServer) PreWrite added in v1.0.0

func (es *EventServer) PreWrite()

PreWrite fires just before any data is written to any client socket, this event function is usually used to put some code of logging/counting/reporting or any prepositive operations before writing data to client.

func (*EventServer) React added in v1.0.0

func (es *EventServer) React(frame []byte, c Conn) (out []byte, action Action)

React fires when a connection sends the server data. Call c.Read() or c.ReadN(n) within the parameter:c to read incoming data from client. Parameter:out is the return value which is going to be sent back to the client.

func (*EventServer) Tick added in v1.0.0

func (es *EventServer) Tick() (delay time.Duration, action Action)

Tick fires immediately after the server starts and will fire again following the duration specified by the delay return value.

type FixedLengthFrameCodec added in v1.0.0

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

FixedLengthFrameCodec encodes/decodes fixed-length-separated frames into/from TCP stream.

func NewFixedLengthFrameCodec added in v1.0.0

func NewFixedLengthFrameCodec(frameLength int) *FixedLengthFrameCodec

NewFixedLengthFrameCodec instantiates and returns a codec with fixed length.

func (*FixedLengthFrameCodec) Decode added in v1.0.0

func (cc *FixedLengthFrameCodec) Decode(c Conn) ([]byte, error)

Decode ...

func (*FixedLengthFrameCodec) Encode added in v1.0.0

func (cc *FixedLengthFrameCodec) Encode(c Conn, buf []byte) ([]byte, error)

Encode ...

type ICodec added in v1.0.0

type ICodec interface {
	// Encode encodes frames upon server responses into TCP stream.
	Encode(c Conn, buf []byte) ([]byte, error)
	// Decode decodes frames from TCP stream via specific implementation.
	Decode(c Conn) ([]byte, error)
}

ICodec is the interface of gnet codec.

type LengthFieldBasedFrameCodec added in v1.0.0

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

LengthFieldBasedFrameCodec is the refactoring from https://github.com/smallnest/goframe/blob/master/length_field_based_frameconn.go, licensed by Apache License 2.0. It encodes/decodes frames into/from TCP stream with value of the length field in the message.

func NewLengthFieldBasedFrameCodec added in v1.0.0

func NewLengthFieldBasedFrameCodec(ec EncoderConfig, dc DecoderConfig) *LengthFieldBasedFrameCodec

NewLengthFieldBasedFrameCodec instantiates and returns a codec based on the length field. It is the go implementation of netty LengthFieldBasedFrameecoder and LengthFieldPrepender. you can see javadoc of them to learn more details.

func (*LengthFieldBasedFrameCodec) Decode added in v1.0.0

func (cc *LengthFieldBasedFrameCodec) Decode(c Conn) ([]byte, error)

Decode ...

func (*LengthFieldBasedFrameCodec) Encode added in v1.0.0

func (cc *LengthFieldBasedFrameCodec) Encode(c Conn, buf []byte) (out []byte, err error)

Encode ...

type LineBasedFrameCodec added in v1.0.0

type LineBasedFrameCodec struct {
}

LineBasedFrameCodec encodes/decodes line-separated frames into/from TCP stream.

func (*LineBasedFrameCodec) Decode added in v1.0.0

func (cc *LineBasedFrameCodec) Decode(c Conn) ([]byte, error)

Decode ...

func (*LineBasedFrameCodec) Encode added in v1.0.0

func (cc *LineBasedFrameCodec) Encode(c Conn, buf []byte) ([]byte, error)

Encode ...

type LoadBalancing added in v1.1.0

type LoadBalancing int

LoadBalancing represents the the type of load-balancing algorithm.

const (
	// RoundRobin assigns the next accepted connection to the event-loop by polling event-loop list.
	RoundRobin LoadBalancing = iota

	// LeastConnections assigns the next accepted connection to the event-loop that is
	// serving the least number of active connections at the current time.
	LeastConnections

	// SourceAddrHash assignes the next accepted connection to the event-loop by hashing the remote address.
	SourceAddrHash
)

type Option added in v1.0.0

type Option func(opts *Options)

Option is a function that will set up option.

func WithCodec added in v1.0.0

func WithCodec(codec ICodec) Option

WithCodec sets up a codec to handle TCP stream.

func WithLoadBalancing added in v1.1.0

func WithLoadBalancing(lb LoadBalancing) Option

WithLoadBalancing sets up the load-balancing algorithm in gnet server.

func WithLockOSThread added in v1.3.0

func WithLockOSThread(lockOSThread bool) Option

WithLockOSThread sets up lockOSThread mode for I/O event-loops.

func WithLogger added in v1.0.0

func WithLogger(logger logging.Logger) Option

WithLogger sets up a customized logger.

func WithMulticore added in v1.0.0

func WithMulticore(multicore bool) Option

WithMulticore sets up multi-cores in gnet server.

func WithNumEventLoop added in v1.0.0

func WithNumEventLoop(numEventLoop int) Option

WithNumEventLoop sets up NumEventLoop in gnet server.

func WithOptions added in v1.0.0

func WithOptions(options Options) Option

WithOptions sets up all options.

func WithReusePort added in v1.0.0

func WithReusePort(reusePort bool) Option

WithReusePort sets up SO_REUSEPORT socket option.

func WithTCPKeepAlive added in v1.0.0

func WithTCPKeepAlive(tcpKeepAlive time.Duration) Option

WithTCPKeepAlive sets up SO_KEEPALIVE socket option.

func WithTicker added in v1.0.0

func WithTicker(ticker bool) Option

WithTicker indicates that a ticker is set.

type Options

type Options struct {
	// Multicore indicates whether the server will be effectively created with multi-cores, if so,
	// then you must take care with synchronizing memory between all event callbacks, otherwise,
	// it will run the server with single thread. The number of threads in the server will be automatically
	// assigned to the value of logical CPUs usable by the current process.
	Multicore bool

	// LockOSThread is used to determine whether each I/O event-loop is associated to an OS thread, it is useful when you
	// need some kind of mechanisms like thread local storage, or invoke certain C libraries (such as graphics lib: GLib)
	// that require thread-level manipulation via cgo, or want all I/O event-loops to actually run in parallel for a
	// potential higher performance.
	LockOSThread bool

	// LB represents the load-balancing algorithm used when assigning new connections.
	LB LoadBalancing

	// NumEventLoop is set up to start the given number of event-loop goroutine.
	// Note: Setting up NumEventLoop will override Multicore.
	NumEventLoop int

	// ReusePort indicates whether to set up the SO_REUSEPORT socket option.
	ReusePort bool

	// Ticker indicates whether the ticker has been set up.
	Ticker bool

	// TCPKeepAlive sets up a duration for (SO_KEEPALIVE) socket option.
	TCPKeepAlive time.Duration

	// ICodec encodes and decodes TCP stream.
	Codec ICodec

	// Logger is the customized logger for logging info, if it is not set,
	// then gnet will use the default logger powered by go.uber.org/zap.
	Logger logging.Logger
}

Options are set when the client opens.

type Server

type Server struct {

	// Multicore indicates whether the server will be effectively created with multi-cores, if so,
	// then you must take care of synchronizing the shared data between all event callbacks, otherwise,
	// it will run the server with single thread. The number of threads in the server will be automatically
	// assigned to the value of logical CPUs usable by the current process.
	Multicore bool

	// The Addr parameter is the listening address that align
	// with the addr string passed to the Serve function.
	Addr net.Addr

	// NumEventLoop is the number of event-loops that the server is using.
	NumEventLoop int

	// ReusePort indicates whether SO_REUSEPORT is enable.
	ReusePort bool

	// TCPKeepAlive (SO_KEEPALIVE) socket option.
	TCPKeepAlive time.Duration
	// contains filtered or unexported fields
}

Server represents a server context which provides information about the running server and has control functions for managing state.

func (Server) CountConnections added in v1.1.0

func (s Server) CountConnections() (count int)

CountConnections counts the number of currently active connections and returns it.

Directories

Path Synopsis
pool

Jump to

Keyboard shortcuts

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