github.com/ianic/xnet/aio@v0.0.0-20230924160527-cee7f41ab201/example/echo/main.go (about) 1 package main 2 3 import ( 4 "log/slog" 5 6 "github.com/ianic/xnet/aio" 7 "github.com/ianic/xnet/aio/signal" 8 ) 9 10 func main() { 11 if err := run("127.0.0.1:4242"); err != nil { 12 slog.Error("run", "error", err) 13 } 14 } 15 16 func run(addr string) error { 17 // start loop 18 loop, err := aio.New(aio.Options{ 19 RingEntries: 128, 20 RecvBuffersCount: 256, 21 RecvBufferLen: 1024, 22 }) 23 if err != nil { 24 return err 25 } 26 defer loop.Close() 27 28 // called when tcp listener accepts tcp connection 29 tcpAccepted := func(fd int, tc *aio.TCPConn) { 30 tc.Bind(&conn{fd: fd, sender: tc}) 31 } 32 33 // start listener 34 _, err = loop.Listen(addr, tcpAccepted) 35 if err != nil { 36 return err 37 } 38 slog.Debug("started server", "addr", addr) 39 // run util interrupted 40 ctx := signal.InterruptContext() 41 if err := loop.Run(ctx); err != nil { 42 return err 43 } 44 return nil 45 } 46 47 type Sender interface { 48 Send(data []byte) 49 } 50 51 type conn struct { 52 fd int 53 sender Sender 54 } 55 56 func (c *conn) Received(data []byte) { 57 slog.Debug("received", "fd", c.fd, "len", len(data)) 58 dst := make([]byte, len(data)) 59 copy(dst, data) 60 c.sender.Send(dst) 61 } 62 63 func (c *conn) Closed(error) { 64 slog.Debug("closed", "fd", c.fd) 65 } 66 func (c *conn) Sent() { 67 slog.Debug("sent", "fd", c.fd) 68 }