➡️➡️ https://github.com/Allenxuxu/gev
gev
is a lightweight, fast non-blocking TCP network library based on Reactor mode.
Features
- High-performance event loop based on epoll and kqueue
- Support multi-core and multi-threading
- Dynamic expansion of read and write buffers implemented by Ring Buffer
- Asynchronous read and write
- SO_REUSEPORT port reuse support
Network model
gev
uses only a few goroutines, one of them listens for connections and the others (work coroutines) handle read and write events of connected clients. The count of work coroutines is configurable, which is the core number of host CPUs by default.
Performance Test
Test environment: Ubuntu18.04 | 4 Virtual CPUs | 4.0 GiB
Throughput Test
limit GOMAXPROCS=1(Single thread),1 work goroutine
limit GOMAXPROCS=4,4 work goroutine
Other Test
Compared with the simple performance of similar libraries, the pressure measurement method is the same as the evio project.
- gnet
- eviop
- evio
- net (StdLib)
limit GOMAXPROCS=1,1 work goroutine
limit GOMAXPROCS=1,4 work goroutine
limit GOMAXPROCS=4,4 work goroutine
Install
go get -u github.com/Allenxuxu/gev
Getting start
package main
import (
"log"
"github.com/Allenxuxu/gev"
"github.com/Allenxuxu/gev/connection"
"github.com/Allenxuxu/ringbuffer"
)
type example struct{}
func (s *example) OnConnect(c *connection.Connection) {
log.Println(" OnConnect : ", c.PeerAddr())
}
func (s *example) OnMessage(c *connection.Connection, buffer *ringbuffer.RingBuffer) (out []byte) {
log.Println("OnMessage")
first, end := buffer.PeekAll()
out = first
if len(end) > 0 {
out = append(out, end...)
}
buffer.RetrieveAll()
return
}
func (s *example) OnClose(c *connection.Connection) {
log.Println("OnClose")
}
func main() {
handler := new(example)
s, err := gev.NewServer(handler,
gev.Address(":1833"),
gev.NumLoops(2),
gev.ReusePort(true))
if err != nil {
panic(err)
}
s.Start()
}
Handler is an interface that programs must implement.
type Handler interface {
OnConnect(c *connection.Connection)
OnMessage(c *connection.Connection, buffer *ringbuffer.RingBuffer) []byte
OnClose(c *connection.Connection)
}
func NewServer(handler Handler, opts ...Option) (server *Server, err error) {
When the message arrivals, gev
will send data within a slice back to the client by calling OnMessage.
func (s *example) OnMessage(c *connection.Connection, buffer *ringbuffer.RingBuffer) (out []byte)
There is also a Send method that can be used for sending data. But Send puts the data to Event-Loop and invokes it to send the data rather than sending data by itself immediately.
Check out the example Server timing push for a detailed.
func (c *Connection) Send(buffer []byte) error
ShutdownWrite works for reverting connected status to false and closing connection.
Check out the example Maximum connections for a detailed.
func (c *Connection) ShutdownWrite() error
RingBuffer is a dynamical expansion implementation of circular buffer.
Top comments (0)