package main import "os" import "io" import "fmt" import "log" import "errors" import "git.tebibyte.media/sashakoshka/hopp" import "git.tebibyte.media/sashakoshka/hopp/examples/ping" func main() { name := os.Args[0] if len(os.Args) != 2 { fmt.Fprintf(os.Stderr, "Usage: %s HOST:PORT\n", name) os.Exit(2) } address := os.Args[1] err := listen(address) handleErr(1, err) } func listen(address string) error { listener, err := hopp.Listen("tcp", address, nil) if err != nil { return err } log.Printf("(i) hosting on %s", address) for { conn, err := listener.Accept() if err != nil { return err } go run(conn) } } func run(conn hopp.Conn) { log.Printf("-=E %v connected", conn.RemoteAddr()) defer log.Printf("X=- %v disconnected", conn.RemoteAddr()) defer conn.Close() for { trans, err := conn.AcceptTrans() if err != nil { if !errors.Is(err, io.EOF) { log.Printf("XXX %v failed: %v", conn.RemoteAddr(), err) } return } go runTrans(conn, trans) } } func runTrans(conn hopp.Conn, trans hopp.Trans) { for { message, _, err := ping.Receive(trans) if err != nil { if !errors.Is(err, io.EOF) { log.Printf("XXX failed to receive message: %v", err) } return } switch message := message.(type) { case *ping.MessagePing: log.Printf("--> ping (%d) from %v", message, conn.RemoteAddr()) response := ping.MessagePong(*message) _, err := ping.Send(trans, &response) if err != nil { log.Printf("XXX failed to send message: %v", err) return } } } } func handleErr(code int, err error) { if err != nil { fmt.Fprintf(os.Stderr, "%s: %v\n", os.Args[0], err) os.Exit(code) } }