diff --git a/examples/1proc/main.go b/examples/1proc/main.go new file mode 100644 index 0000000..a96f424 --- /dev/null +++ b/examples/1proc/main.go @@ -0,0 +1,86 @@ +package main + +import "io" +import "log" +import "time" +import "errors" +import "context" +import "git.tebibyte.media/sashakoshka/hopp" + +var network = "tcp" +var addr = "localhost:7959" + +func main() { + go func() { + defer log.Println("SERVER closing") + + listener, err := hopp.Listen(network, addr, nil) + if err != nil { log.Println("SERVER", err); return } + log.Println("SERVER listening") + conn, err := listener.Accept() + if err != nil { log.Println("SERVER", err); return } + defer conn.Close() + + trans, err := conn.AcceptTrans() + if err != nil { log.Println("SERVER", err); return } + defer trans.Close() + + for { + method, data, err := trans.Receive() + if err != nil { log.Println("SERVER", err); return } + log.Println("SERVER got", method, data) + log.Println("SERVER send", method, data) + err = trans.Send(1, data[:]) + if err != nil { log.Println("SERVER", err); return } + } + }() + + time.Sleep(time.Second * 2) + + func() { + log.Println("CLIENT dialing") + conn, err := hopp.Dial(context.Background(), network, addr, nil) + if err != nil { log.Fatalln("CLIENT", err) } + log.Println("CLIENT dialed") + + trans, err := conn.OpenTrans() + if err != nil { + log.Println("CLIENT", err) + return + } + + go func() { + for { + method, data, err := trans.Receive() + if err != nil { + if !errors.Is(err, io.EOF) { + log.Printf("CLIENT failed to receive message: %v", err) + } + return + } + log.Println("CLIENT got", method, data) + } + }() + + data := [1]byte { } + for { + log.Println("CLIENT send", 1, data) + err := trans.Send(1, data[:]) + if err != nil { + log.Println("CLIENT", err) + return + } + data[0] ++ + time.Sleep(time.Second) + } + + log.Println("CLIENT waiting for connection close...") + trans, err = conn.AcceptTrans() + if !errors.Is(err, io.EOF) { + log.Println("CLIENT wrong error:", err) + log.Fatalln("CLIENT trans:", trans) + } + log.Println("CLIENT DONE") + conn.Close() + }() +} diff --git a/examples/min/client/main.go b/examples/min/client/main.go new file mode 100644 index 0000000..fce8651 --- /dev/null +++ b/examples/min/client/main.go @@ -0,0 +1,84 @@ +package main + +import "io" +import "os" +import "log" +import "fmt" +import "time" +import "context" +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] + + conn, err := dial(address) + handleErr(1, err) + trans, err := conn.OpenTrans() + handleErr(1, err) + + go func() { + defer fmt.Fprintf(os.Stdout, "(i) disconnected\n") + for { + // message, _, err := ping.Receive(trans) + // if err != nil { + // if !errors.Is(err, io.EOF) { + // handleErr(1, err) + // } + // break + // } + // switch message := message.(type) { + // case *ping.MessagePong: + // log.Printf("--> pong (%d) from %v", message, address) + // } + method, reader, err := trans.ReceiveReader() + if err != nil { + log.Printf("CLIENT recv: %v", err) + return + } + data, err := io.ReadAll(reader) + if err != nil { + log.Printf("CLIENT recv: %v", err) + return + } + log.Println("CLIENT got", method, data) + } + }() + + // message := ping.MessagePing(0) + // for { + // log.Printf("<-- ping (%d)", message) + // _, err := ping.Send(trans, &message) + // handleErr(1, err) + // message ++ + // time.Sleep(time.Second) + // } + data := [1]byte { } + for { + log.Println("CLIENT send", 1, data) + err := trans.Send(1, data[:]) + handleErr(1, err) + data[0] ++ + time.Sleep(time.Second) + } +} + +func dial(address string) (hopp.Conn, error) { + ctx, done := context.WithTimeout(context.Background(), 16 * time.Second) + defer done() + conn, err := hopp.Dial(ctx, "tcp", address, nil) + if err != nil { return nil, err } + return conn, nil +} + +func handleErr(code int, err error) { + if err != nil { + fmt.Fprintf(os.Stderr, "%s: %v\n", os.Args[0], err) + os.Exit(code) + } +} diff --git a/examples/min/server/main.go b/examples/min/server/main.go new file mode 100644 index 0000000..2b4e52c --- /dev/null +++ b/examples/min/server/main.go @@ -0,0 +1,97 @@ +package main + +import "io" +import "os" +import "fmt" +import "log" +import "errors" +import "git.tebibyte.media/sashakoshka/hopp" +// import "git.tebibyte.media/sashakoshka/hopp/examples/ping" + +var network = "tcp" +var addr = "localhost:7959" + +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(addr string) error { + defer log.Println("(i) closing") + + listener, err := hopp.Listen(network, addr, nil) + if err != nil { return err } + log.Printf("(i) hosting on %s", addr) + 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) { + defer trans.Close() + + 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 + // } + // } + method, reader, err := trans.ReceiveReader() + if err != nil { log.Println("SERVER", err); return } + data, err := io.ReadAll(reader) + if err != nil { log.Println("SERVER", err); return } + log.Println("SERVER got", method, data) + log.Println("SERVER send", method, data) + func (){ + writer, err := trans.SendWriter(1) + if err != nil { log.Println("SERVER", err); return } + defer writer.Close() + _, err = writer.Write(data[:]) + if err != nil { log.Println("SERVER", 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) + } +} diff --git a/examples/ping/client/main.go b/examples/ping/client/main.go index 4fd92a3..2bff04d 100644 --- a/examples/ping/client/main.go +++ b/examples/ping/client/main.go @@ -4,10 +4,9 @@ import "os" import "io" import "fmt" import "log" -import "net" import "time" import "errors" -// import "context" +import "context" import "git.tebibyte.media/sashakoshka/hopp" import "git.tebibyte.media/sashakoshka/hopp/examples/ping" @@ -25,41 +24,37 @@ func main() { handleErr(1, err) go func() { - defer fmt.Fprintf(os.Stdout, "(i) disconnected\n") + message := ping.MessagePing(0) for { - message, _, err := ping.Receive(trans) - if err != nil { - if !errors.Is(err, io.EOF) { - handleErr(1, err) - } - break - } - switch message := message.(type) { - case *ping.MessagePong: - log.Printf("--> pong (%d) from %v", message, address) - } + log.Printf("<-- ping (%d)", message) + _, err := ping.Send(trans, &message) + handleErr(1, err) + message ++ + time.Sleep(time.Second) } }() - message := ping.MessagePing(0) + defer fmt.Fprintf(os.Stdout, "(i) disconnected\n") for { - log.Printf("<-- ping (%d)", message) - _, err := ping.Send(trans, &message) - handleErr(1, err) - message ++ - time.Sleep(time.Second) + message, _, err := ping.Receive(trans) + if err != nil { + if !errors.Is(err, io.EOF) { + handleErr(1, err) + } + break + } + switch message := message.(type) { + case *ping.MessagePong: + log.Printf("--> pong (%d) from %v", message, address) + } } } func dial(address string) (hopp.Conn, error) { - // ctx, done := context.WithTimeout(context.Background(), 16 * time.Second) - // defer done() - // conn, err := hopp.Dial(ctx, "tcp", address, nil) - // if err != nil { return nil, err } - // return conn, nil - underlying, err := net.Dial("tcp", address) + ctx, done := context.WithTimeout(context.Background(), 16 * time.Second) + defer done() + conn, err := hopp.Dial(ctx, "tcp", address, nil) if err != nil { return nil, err } - conn := hopp.AdaptA(underlying, hopp.ServerSide) return conn, nil }