Documentation
¶
Overview ¶
evio is forked from https://github.com/tidwall/evio
Package evio is an event loop networking framework.
Index ¶
Examples ¶
Constants ¶
const DefaultConnDeadline int64 = 15
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Conn ¶
type Conn interface {
// Context returns a user-defined context.
Context() any
// SetContext sets a user-defined context.
SetContext(any)
// AddrIndex is the index of server address that was passed to the Serve call.
AddrIndex() int
// LocalAddr is the connection's local socket address.
LocalAddr() net.Addr
// RemoteAddr is the connection's remote peer address.
RemoteAddr() net.Addr
// Wake triggers a Data event for this connection.
Wake()
}
Conn is an evio connection.
type Engine ¶
type Engine interface {
Start()
Stop()
Serve() error
Ready() chan bool
Clear()
HasErr() bool
Errors() iter.Seq[error]
}
Engine is an abstract Server definition
Example ¶
package main
import (
"fmt"
"log"
"net"
"os"
"strings"
"time"
)
func main() {
var (
port = 6399
unixsocket = "example-test.sock"
)
var (
events Events
)
events.NumLoops = 2
events.OnServing = func(srv ServerInfo) (action Action) {
// log.Printf("echo server started on port %d (loops: %d)", port, srv.NumLoops)
if unixsocket != "" {
// log.Printf("echo server started at %s (loops: %d)", unixsocket, srv.NumLoops)
}
return
}
events.OnOpened = func(ec Conn) (out []byte, opts Options, action Action) {
// log.Printf("opened: %v", ec.RemoteAddr())
ec.SetContext((*InputStream)(nil))
opts.ReuseInputBuffer = true
opts.TCPKeepAlive = 30 * time.Second
return
}
events.OnClosed = func(ec Conn, err error) (action Action) {
// log.Printf("closed: %v", ec.RemoteAddr())
return
}
events.OnData = makeHandler()
addrs := []string{fmt.Sprintf("tcp://:%d", port)}
if unixsocket != "" {
addrs = append(addrs, fmt.Sprintf("unix://%s", unixsocket))
}
var err error
var c net.Conn
serv, err := NewEngine(events, addrs...)
if err != nil {
log.Fatal(err)
}
serv.Start()
<-serv.Ready()
if unixsocket != "" {
c, err = net.Dial("unix", unixsocket)
} else {
c, err = net.Dial("tcp", "127.0.0.1:6399")
}
if err != nil {
log.Fatal(err)
}
defer func() {
_ = c.Close()
serv.Stop()
serv.Clear()
_ = os.Remove(unixsocket)
}()
_, err = c.Write([]byte("GET"))
if err != nil {
log.Println(err)
return
}
var b = make([]byte, 128)
_, err = c.Read(b)
if err != nil {
log.Println(err)
return
}
fmt.Printf("%s", strings.TrimSpace(string(b)))
}
func makeHandler() func(Conn, []byte) ([]byte, Action) {
return func(ec Conn, in []byte) (out []byte, action Action) {
if in == nil {
log.Printf("wake from %s\n", ec.RemoteAddr())
return nil, Close
}
ec.SetContext((*InputStream)(nil))
out = in
return
}
}
func NewEngine ¶
NewEngine create a evloop server instance.
It run many event-loops to process network connection ¶
Addresses 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.
type Events ¶
type Events struct {
// NumLoops sets the number of loops to use for the server. Setting this
// to a value greater than 1 will effectively make the server
// multithreaded for multi-core machines. Which means you must take care
// with synchonizing memory between all event callbacks. Setting to 0 or 1
// will run the server single-threaded. Setting to -1 will automatically
// assign this value equal to runtime.NumProcs().
NumLoops int
// ConnDeadline sets dealine duration that apply to every net connection
// This value is measured in seconds. (Time of idle)
ConnDeadline int64
// LoadBalance sets the load balancing method. Load balancing is always a
// best effort to attempt to distribute the incoming connections between
// multiple loops. This option is only works when NumLoops is set.
LoadBalance LoadBalance
// Serving fires when the server can accept connections. The server
// parameter has information and various utilities.
OnServing func(server ServerInfo) (action Action)
// Opened fires when a new connection has opened.
// The info parameter has information about the connection such as
// it's local and remote address.
// Use the out return value to write data to the connection.
// The opts return value is used to set connection options.
OnOpened func(c Conn) (out []byte, opts Options, action Action)
// Closed fires when a connection has closed.
// The err parameter is the last known connection error.
OnClosed func(c Conn, err error) (action Action)
// Detached fires when a connection has been previously detached.
// Once detached it's up to the receiver of this event to manage the
// state of the connection. The Closed event will not be called for
// this connection.
// The conn parameter is a ReadWriteCloser that represents the
// underlying socket connection. It can be freely used in goroutines
// and should be closed when it's no longer needed.
OnDetached func(c Conn, rwc io.ReadWriteCloser) (action Action)
// PreWrite fires just before any data is written to any client socket.
OnPreWrite func()
// Data fires when a connection sends the server data.
// The in parameter is the incoming data.
// Use the out return value to write data to the connection.
OnData func(c Conn, in []byte) (out []byte, action Action)
// Tick fires immediately after the server starts and will fire again
// following the duration specified by the delay return value.
OnTick func() (delay time.Duration, action Action)
}
Events represents the server events for the Serve call. Each event has an Action return value that is used manage the state of the connection and server.
type InputStream ¶
type InputStream struct {
// contains filtered or unexported fields
}
InputStream is a helper type for managing input streams from inside the Data event.
func (*InputStream) Begin ¶
func (is *InputStream) Begin(packet []byte) (data []byte)
Begin accepts a new packet and returns a working sequence of unprocessed bytes.
func (*InputStream) End ¶
func (is *InputStream) End(data []byte)
End shifts the stream to match the unprocessed data.
type LoadBalance ¶
type LoadBalance int
LoadBalance sets the load balancing method.
const ( // Random requests that connections are randomly distributed. Random LoadBalance = iota // RoundRobin requests that connections are distributed to a loop in a // round-robin fashion. RoundRobin // LeastConnections assigns the next accepted connection to the loop with // the least number of active connections. LeastConnections )
type Options ¶
type Options struct {
// TCPKeepAlive (SO_KEEPALIVE) socket option.
TCPKeepAlive time.Duration
// ReuseInputBuffer will forces the connection to share and reuse the
// same input packet buffer with all other connections that also use
// this option.
// Default value is false, which means that all input data which is
// passed to the Data event will be a uniquely copied []byte slice.
ReuseInputBuffer bool
}
Options are set when the client opens.
type ServerInfo ¶
type ServerInfo struct {
// The addrs parameter is an array of listening addresses that align
// with the addr strings passed to the Serve function.
Addrs []net.Addr
// NumLoops is the number of loops that the server is using.
NumLoops int
}
ServerInfo represents a server context which provides information about the running server and has control functions for managing state.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package internal is the concrete implementation of epoll and kqueue in low-level OpenPoll factory method is package entry.
|
Package internal is the concrete implementation of epoll and kqueue in low-level OpenPoll factory method is package entry. |
|
Package reuseport provides Listen and Dial functions that set socket options in order to be able to reuse ports.
|
Package reuseport provides Listen and Dial functions that set socket options in order to be able to reuse ports. |