event is a network I/O event notification library for Go. It uses epoll and kqueue to poll I/O events that is fast and low memory usage. It works in a similar manner as libevent.
The goal of event is to provide a BASIC tool for building high performance network applications.
Note: All development is done on a Raspberry Pi 4B.
Features
- Supports Read/Write/Timeout events
- Flexible timer event and ticker event
- Supports event priority
- Simple API
- Low memory usage
Getting Started
Installing
To start using event, just run go get:
$ go get -u github.com/cheng-zhongliang/event
Event
EvReadfires when the fd is readable.EvWritefires when the fd is writable.EvTimeoutfires when the timeout expires.
When the event is triggered, the callback function will be called.
Read/Write/Timeout
These events can be used in combination.
base := event.NewBase() ev := event.New(base, fd, event.EvRead|event.Timeout, callback, arg) ev.Attach(time.Second)
When the fd is readable or timeout expires, this event will be triggered.
Option
The event is one-shot by default. If you want to persist, you can set the EvPersist option.
ev := event.New(base, fd, event.EvRead|event.EvPersist, callback, arg)
Timer
The timer is a one-shot event that will be triggered after the timeout expires.
base := event.NewBase() ev := event.NewTimer(base, callback, arg) ev.Attach(time.Second)
Ticker
The ticker is a repeating event that will be triggered every time the timeout expires.
base := event.NewBase() ev := event.NewTicker(base, callback, arg) ev.Attach(time.Second)
Priority
When events are triggered together, high priority events will be dispatched first.
ev := event.New(base, fd, event.EvRead, callback, arg) ev.SetPriority(event.HP)
Usage
Example echo server that binds to port 1246:
package main import ( "syscall" "github.com/cheng-zhongliang/event" ) func main() { base, err := event.NewBase() if err != nil { panic(err) } fd := socket() ev := event.New(base, fd, event.EvRead|event.EvPersist, accept, base) if err := ev.Attach(0); err != nil { panic(err) } if err := base.Dispatch(); err != nil && err != syscall.EBADF { panic(err) } syscall.Close(fd) } func socket() int { addr := syscall.SockaddrInet4{Port: 1246, Addr: [4]byte{0, 0, 0, 0}} fd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_STREAM, syscall.IPPROTO_TCP) if err != nil { panic(err) } if err := syscall.Bind(fd, &addr); err != nil { panic(err) } err = syscall.Listen(fd, syscall.SOMAXCONN) if err != nil { panic(err) } return fd } func accept(fd int, events uint32, arg interface{}) { base := arg.(*event.EventBase) clientFd, _, err := syscall.Accept(fd) if err != nil { panic(err) } ev := event.New(base, clientFd, event.EvRead|event.EvPersist, echo, nil) if err := ev.Attach(0); err != nil { panic(err) } } func echo(fd int, events uint32, arg interface{}) { buf := make([]byte, 0xFFF) n, err := syscall.Read(fd, buf) if err != nil { panic(err) } if _, err := syscall.Write(fd, buf[:n]); err != nil { panic(err) } }
Connect to the echo server: