package main import ( "context" "fmt" "net" "os" "os/signal" "syscall" v1 "git.thisco.de/vbatts/handshake/api/v1" "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/urfave/cli" "google.golang.org/grpc" ) func main() { app := cli.NewApp() app.Name = "handshake" app.Flags = []cli.Flag{ cli.StringFlag{ Name: "address,a", Usage: "server address", Value: "0.0.0.0:1111", }, } app.Commands = []cli.Command{ serverCommand, clientCommand, } app.Before = func(clix *cli.Context) error { if clix.GlobalBool("debug") { logrus.SetLevel(logrus.DebugLevel) } return nil } if err := app.Run(os.Args); err != nil { logrus.Fatal(err) } } var serverCommand = cli.Command{ Name: "server", Action: func(clix *cli.Context) error { var ( address = clix.GlobalString("address") ) gs := grpc.NewServer() logrus.Debug("setting up gRPC service") v1.RegisterHandshakeServer(gs, &HandshakeServer{}) signals := make(chan os.Signal, 32) signal.Notify(signals, syscall.SIGTERM, syscall.SIGINT) go func() { <-signals gs.Stop() }() l, err := net.Listen("tcp", address) if err != nil { return errors.Wrap(err, "listen tcp") } defer l.Close() logrus.Infof("listening on %q", address) return gs.Serve(l) }, } var clientCommand = cli.Command{ Name: "client", Action: func(clix *cli.Context) error { var ( address = clix.GlobalString("address") ) conn, err := grpc.Dial(address, grpc.WithInsecure()) if err != nil { return errors.Wrap(err, "dialing server") } defer conn.Close() ctx, cancel := context.WithCancel(context.Background()) signals := make(chan os.Signal) signal.Notify(signals, syscall.SIGTERM, syscall.SIGINT) go func() { <-signals cancel() }() client := v1.NewHandshakeClient(conn) req := v1.Request{ Pubkey: "facecafe", Msg: "hello", } resp, err := client.Hello(ctx, &req) if err != nil { return errors.Wrap(err, "client hello") } logrus.Infof("pubkey: %q; challenge: %q", resp.Pubkey, resp.Msg) return nil }, } type HandshakeServer struct { } func (hs *HandshakeServer) Hello(ctx context.Context, req *v1.Request) (*v1.Response, error) { logrus.Infof("pubkey: %q", req.Pubkey) resp := v1.Response{ Pubkey: "deadbeef", Msg: fmt.Sprintf("did you say %q?", req.Msg), } //return nil, errors.New("not implemented") return &resp, nil }