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  }