diff options
Diffstat (limited to 'grpc/examples')
-rw-r--r-- | grpc/examples/README.md | 7 | ||||
-rw-r--r-- | grpc/examples/generate.sh | 18 | ||||
-rw-r--r-- | grpc/examples/go/greeter/.gitignore | 2 | ||||
-rw-r--r-- | grpc/examples/go/greeter/README.md | 25 | ||||
-rw-r--r-- | grpc/examples/go/greeter/client/go.mod | 11 | ||||
-rw-r--r-- | grpc/examples/go/greeter/client/main.go | 74 | ||||
-rw-r--r-- | grpc/examples/go/greeter/models/Greeter_grpc.go | 158 | ||||
-rw-r--r-- | grpc/examples/go/greeter/models/HelloReply.go | 52 | ||||
-rw-r--r-- | grpc/examples/go/greeter/models/HelloRequest.go | 52 | ||||
-rw-r--r-- | grpc/examples/go/greeter/models/go.mod | 8 | ||||
-rw-r--r-- | grpc/examples/go/greeter/server/go.mod | 11 | ||||
-rw-r--r-- | grpc/examples/go/greeter/server/main.go | 78 | ||||
-rw-r--r-- | grpc/examples/greeter.fbs | 14 |
13 files changed, 510 insertions, 0 deletions
diff --git a/grpc/examples/README.md b/grpc/examples/README.md new file mode 100644 index 00000000..f5694a84 --- /dev/null +++ b/grpc/examples/README.md @@ -0,0 +1,7 @@ +## Languages known issues + +### Go + +- Always requires the `content-type` of the payload to be set to `application/grpc+flatbuffers` + +example: `.SayHello(ctx, b, grpc.CallContentSubtype("flatbuffers"))`
\ No newline at end of file diff --git a/grpc/examples/generate.sh b/grpc/examples/generate.sh new file mode 100644 index 00000000..4f481919 --- /dev/null +++ b/grpc/examples/generate.sh @@ -0,0 +1,18 @@ +current_dir=`pwd` + +cd ../.. + +main_dir=`pwd` + +cd ${current_dir} + +alias fbc='${main_dir}/Debug/flatc' +generator="--grpc $current_dir/greeter.fbs" + +# Regenerate Go lang code +cd go/ + +cd greeter +fbc --go ${generator} + +cd ../..
\ No newline at end of file diff --git a/grpc/examples/go/greeter/.gitignore b/grpc/examples/go/greeter/.gitignore new file mode 100644 index 00000000..535db5e3 --- /dev/null +++ b/grpc/examples/go/greeter/.gitignore @@ -0,0 +1,2 @@ +**/server +**/client
\ No newline at end of file diff --git a/grpc/examples/go/greeter/README.md b/grpc/examples/go/greeter/README.md new file mode 100644 index 00000000..33905088 --- /dev/null +++ b/grpc/examples/go/greeter/README.md @@ -0,0 +1,25 @@ +# Go Greeter example + +## Project Structure + + . + ├── server # Server module + ├── client # Client module + ├── models # Flatbuffers models & main grpc code. + └── README.md + +## How to run Server: + +- `cd server` + +- `go clean` + +- `go run main.go` + +## How to run Client: + +- `cd client` + +- `go clean` + +- `go run main.go --name NAME`
\ No newline at end of file diff --git a/grpc/examples/go/greeter/client/go.mod b/grpc/examples/go/greeter/client/go.mod new file mode 100644 index 00000000..19689dd4 --- /dev/null +++ b/grpc/examples/go/greeter/client/go.mod @@ -0,0 +1,11 @@ +module github.com/google/flatbuffers/grpc/examples/go/greeter/client + +go 1.15 + +replace github.com/google/flatbuffers/grpc/examples/go/greeter/models v0.0.0 => ../models + +require ( + github.com/google/flatbuffers v1.12.0 + github.com/google/flatbuffers/grpc/examples/go/greeter/models v0.0.0 + google.golang.org/grpc v1.35.0 +) diff --git a/grpc/examples/go/greeter/client/main.go b/grpc/examples/go/greeter/client/main.go new file mode 100644 index 00000000..49935761 --- /dev/null +++ b/grpc/examples/go/greeter/client/main.go @@ -0,0 +1,74 @@ +package main + +import ( + "context" + "flag" + "fmt" + "io" + "log" + "time" + + flatbuffers "github.com/google/flatbuffers/go" + models "github.com/google/flatbuffers/grpc/examples/go/greeter/models" + "google.golang.org/grpc" +) + +var ( + addr = "3000" + name = flag.String("name", "Flatbuffers", "name to be sent to server :D") +) + +func printSayHello(client models.GreeterClient, name string) { + log.Printf("Name to be sent (%s)", name) + b := flatbuffers.NewBuilder(0) + i := b.CreateString(name) + models.HelloRequestStart(b) + models.HelloRequestAddName(b, i) + b.Finish(models.HelloRequestEnd(b)) + + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + request, err := client.SayHello(ctx, b, grpc.CallContentSubtype("flatbuffers")) + if err != nil { + log.Fatalf("%v.SayHello(_) = _, %v: ", client, err) + } + log.Printf("server said %q", request.Message()) +} + +func printSayManyHello(client models.GreeterClient, name string) { + log.Printf("Name to be sent (%s)", name) + b := flatbuffers.NewBuilder(0) + i := b.CreateString(name) + models.HelloRequestStart(b) + models.HelloRequestAddName(b, i) + b.Finish(models.HelloRequestEnd(b)) + + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + stream, err := client.SayManyHellos(ctx, b, grpc.CallContentSubtype("flatbuffers")) + if err != nil { + log.Fatalf("%v.SayManyHellos(_) = _, %v", client, err) + } + for { + request, err := stream.Recv() + if err == io.EOF { + break + } + if err != nil { + log.Fatalf("%v.SayManyHellos(_) = _, %v", client, err) + } + log.Printf("server said %q", request.Message()) + } +} + +func main() { + flag.Parse() + conn, err := grpc.Dial(fmt.Sprintf("localhost:%d", 3000), grpc.WithInsecure(), grpc.WithCodec(flatbuffers.FlatbuffersCodec{})) + if err != nil { + log.Fatalf("fail to dial: %v", err) + } + defer conn.Close() + client := models.NewGreeterClient(conn) + printSayHello(client, *name) + printSayManyHello(client, *name) +} diff --git a/grpc/examples/go/greeter/models/Greeter_grpc.go b/grpc/examples/go/greeter/models/Greeter_grpc.go new file mode 100644 index 00000000..9a2405c7 --- /dev/null +++ b/grpc/examples/go/greeter/models/Greeter_grpc.go @@ -0,0 +1,158 @@ +//Generated by gRPC Go plugin +//If you make any local changes, they will be lost +//source: greeter + +package models + +import ( + context "context" + flatbuffers "github.com/google/flatbuffers/go" + grpc "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +// Client API for Greeter service +type GreeterClient interface { + SayHello(ctx context.Context, in *flatbuffers.Builder, + opts ...grpc.CallOption) (*HelloReply, error) + SayManyHellos(ctx context.Context, in *flatbuffers.Builder, + opts ...grpc.CallOption) (Greeter_SayManyHellosClient, error) +} + +type greeterClient struct { + cc grpc.ClientConnInterface +} + +func NewGreeterClient(cc grpc.ClientConnInterface) GreeterClient { + return &greeterClient{cc} +} + +func (c *greeterClient) SayHello(ctx context.Context, in *flatbuffers.Builder, + opts ...grpc.CallOption) (*HelloReply, error) { + out := new(HelloReply) + err := c.cc.Invoke(ctx, "/models.Greeter/SayHello", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *greeterClient) SayManyHellos(ctx context.Context, in *flatbuffers.Builder, + opts ...grpc.CallOption) (Greeter_SayManyHellosClient, error) { + stream, err := c.cc.NewStream(ctx, &_Greeter_serviceDesc.Streams[0], "/models.Greeter/SayManyHellos", opts...) + if err != nil { + return nil, err + } + x := &greeterSayManyHellosClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type Greeter_SayManyHellosClient interface { + Recv() (*HelloReply, error) + grpc.ClientStream +} + +type greeterSayManyHellosClient struct { + grpc.ClientStream +} + +func (x *greeterSayManyHellosClient) Recv() (*HelloReply, error) { + m := new(HelloReply) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// Server API for Greeter service +type GreeterServer interface { + SayHello(context.Context, *HelloRequest) (*flatbuffers.Builder, error) + SayManyHellos(*HelloRequest, Greeter_SayManyHellosServer) error + mustEmbedUnimplementedGreeterServer() +} + +type UnimplementedGreeterServer struct { +} + +func (UnimplementedGreeterServer) SayHello(context.Context, *HelloRequest) (*flatbuffers.Builder, error) { + return nil, status.Errorf(codes.Unimplemented, "method SayHello not implemented") +} + +func (UnimplementedGreeterServer) SayManyHellos(*HelloRequest, Greeter_SayManyHellosServer) error { + return status.Errorf(codes.Unimplemented, "method SayManyHellos not implemented") +} + +func (UnimplementedGreeterServer) mustEmbedUnimplementedGreeterServer() {} + +type UnsafeGreeterServer interface { + mustEmbedUnimplementedGreeterServer() +} + +func RegisterGreeterServer(s grpc.ServiceRegistrar, srv GreeterServer) { + s.RegisterService(&_Greeter_serviceDesc, srv) +} + +func _Greeter_SayHello_Handler(srv interface{}, ctx context.Context, + dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(HelloRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(GreeterServer).SayHello(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/models.Greeter/SayHello", + } + + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(GreeterServer).SayHello(ctx, req.(*HelloRequest)) + } + return interceptor(ctx, in, info, handler) +} +func _Greeter_SayManyHellos_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(HelloRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(GreeterServer).SayManyHellos(m, &greeterSayManyHellosServer{stream}) +} + +type Greeter_SayManyHellosServer interface { + Send(*flatbuffers.Builder) error + grpc.ServerStream +} + +type greeterSayManyHellosServer struct { + grpc.ServerStream +} + +func (x *greeterSayManyHellosServer) Send(m *flatbuffers.Builder) error { + return x.ServerStream.SendMsg(m) +} + +var _Greeter_serviceDesc = grpc.ServiceDesc{ + ServiceName: "models.Greeter", + HandlerType: (*GreeterServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "SayHello", + Handler: _Greeter_SayHello_Handler, + }, + }, + Streams: []grpc.StreamDesc{ + { + StreamName: "SayManyHellos", + Handler: _Greeter_SayManyHellos_Handler, + ServerStreams: true, + }, + }, +} diff --git a/grpc/examples/go/greeter/models/HelloReply.go b/grpc/examples/go/greeter/models/HelloReply.go new file mode 100644 index 00000000..bb5db407 --- /dev/null +++ b/grpc/examples/go/greeter/models/HelloReply.go @@ -0,0 +1,52 @@ +// Code generated by the FlatBuffers compiler. DO NOT EDIT. + +package models + +import ( + flatbuffers "github.com/google/flatbuffers/go" +) + +type HelloReply struct { + _tab flatbuffers.Table +} + +func GetRootAsHelloReply(buf []byte, offset flatbuffers.UOffsetT) *HelloReply { + n := flatbuffers.GetUOffsetT(buf[offset:]) + x := &HelloReply{} + x.Init(buf, n+offset) + return x +} + +func GetSizePrefixedRootAsHelloReply(buf []byte, offset flatbuffers.UOffsetT) *HelloReply { + n := flatbuffers.GetUOffsetT(buf[offset+flatbuffers.SizeUint32:]) + x := &HelloReply{} + x.Init(buf, n+offset+flatbuffers.SizeUint32) + return x +} + +func (rcv *HelloReply) Init(buf []byte, i flatbuffers.UOffsetT) { + rcv._tab.Bytes = buf + rcv._tab.Pos = i +} + +func (rcv *HelloReply) Table() flatbuffers.Table { + return rcv._tab +} + +func (rcv *HelloReply) Message() []byte { + o := flatbuffers.UOffsetT(rcv._tab.Offset(4)) + if o != 0 { + return rcv._tab.ByteVector(o + rcv._tab.Pos) + } + return nil +} + +func HelloReplyStart(builder *flatbuffers.Builder) { + builder.StartObject(1) +} +func HelloReplyAddMessage(builder *flatbuffers.Builder, message flatbuffers.UOffsetT) { + builder.PrependUOffsetTSlot(0, flatbuffers.UOffsetT(message), 0) +} +func HelloReplyEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT { + return builder.EndObject() +} diff --git a/grpc/examples/go/greeter/models/HelloRequest.go b/grpc/examples/go/greeter/models/HelloRequest.go new file mode 100644 index 00000000..52feab97 --- /dev/null +++ b/grpc/examples/go/greeter/models/HelloRequest.go @@ -0,0 +1,52 @@ +// Code generated by the FlatBuffers compiler. DO NOT EDIT. + +package models + +import ( + flatbuffers "github.com/google/flatbuffers/go" +) + +type HelloRequest struct { + _tab flatbuffers.Table +} + +func GetRootAsHelloRequest(buf []byte, offset flatbuffers.UOffsetT) *HelloRequest { + n := flatbuffers.GetUOffsetT(buf[offset:]) + x := &HelloRequest{} + x.Init(buf, n+offset) + return x +} + +func GetSizePrefixedRootAsHelloRequest(buf []byte, offset flatbuffers.UOffsetT) *HelloRequest { + n := flatbuffers.GetUOffsetT(buf[offset+flatbuffers.SizeUint32:]) + x := &HelloRequest{} + x.Init(buf, n+offset+flatbuffers.SizeUint32) + return x +} + +func (rcv *HelloRequest) Init(buf []byte, i flatbuffers.UOffsetT) { + rcv._tab.Bytes = buf + rcv._tab.Pos = i +} + +func (rcv *HelloRequest) Table() flatbuffers.Table { + return rcv._tab +} + +func (rcv *HelloRequest) Name() []byte { + o := flatbuffers.UOffsetT(rcv._tab.Offset(4)) + if o != 0 { + return rcv._tab.ByteVector(o + rcv._tab.Pos) + } + return nil +} + +func HelloRequestStart(builder *flatbuffers.Builder) { + builder.StartObject(1) +} +func HelloRequestAddName(builder *flatbuffers.Builder, name flatbuffers.UOffsetT) { + builder.PrependUOffsetTSlot(0, flatbuffers.UOffsetT(name), 0) +} +func HelloRequestEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT { + return builder.EndObject() +} diff --git a/grpc/examples/go/greeter/models/go.mod b/grpc/examples/go/greeter/models/go.mod new file mode 100644 index 00000000..01976de5 --- /dev/null +++ b/grpc/examples/go/greeter/models/go.mod @@ -0,0 +1,8 @@ +module github.com/google/flatbuffers/grpc/examples/go/greeter/models + +go 1.15 + +require ( + github.com/google/flatbuffers v1.12.0 + google.golang.org/grpc v1.35.0 +) diff --git a/grpc/examples/go/greeter/server/go.mod b/grpc/examples/go/greeter/server/go.mod new file mode 100644 index 00000000..2572feee --- /dev/null +++ b/grpc/examples/go/greeter/server/go.mod @@ -0,0 +1,11 @@ +module github.com/google/flatbuffers/grpc/examples/go/greeter/server + +go 1.15 + +replace github.com/google/flatbuffers/grpc/examples/go/greeter/models v0.0.0 => ../models + +require ( + github.com/google/flatbuffers v1.12.0 + github.com/google/flatbuffers/grpc/examples/go/greeter/models v0.0.0 + google.golang.org/grpc v1.35.0 +) diff --git a/grpc/examples/go/greeter/server/main.go b/grpc/examples/go/greeter/server/main.go new file mode 100644 index 00000000..61914208 --- /dev/null +++ b/grpc/examples/go/greeter/server/main.go @@ -0,0 +1,78 @@ +package main + +import ( + "context" + "fmt" + "log" + "net" + + flatbuffers "github.com/google/flatbuffers/go" + models "github.com/google/flatbuffers/grpc/examples/go/greeter/models" + "google.golang.org/grpc" + "google.golang.org/grpc/encoding" +) + +var ( + greetings = [...]string{"Hi", "Hallo", "Ciao"} +) + +type greeterServer struct { + models.UnimplementedGreeterServer +} + +func (s *greeterServer) SayHello(ctx context.Context, request *models.HelloRequest) (*flatbuffers.Builder, error) { + v := request.Name() + var m string + if v == nil { + m = "Unknown" + } else { + m = string(v) + } + b := flatbuffers.NewBuilder(0) + idx := b.CreateString("welcome " + m) + models.HelloReplyStart(b) + models.HelloReplyAddMessage(b, idx) + b.Finish(models.HelloReplyEnd(b)) + return b, nil +} + +func (s *greeterServer) SayManyHellos(request *models.HelloRequest, stream models.Greeter_SayManyHellosServer) error { + v := request.Name() + var m string + if v == nil { + m = "Unknown" + } else { + m = string(v) + } + b := flatbuffers.NewBuilder(0) + + for _, greeting := range greetings { + idx := b.CreateString(greeting + " " + m) + models.HelloReplyStart(b) + models.HelloReplyAddMessage(b, idx) + b.Finish(models.HelloReplyEnd(b)) + if err := stream.Send(b); err != nil { + return err + } + } + return nil +} + +func newServer() *greeterServer { + s := &greeterServer{} + return s +} + +func main() { + lis, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", 3000)) + if err != nil { + log.Fatalf("failed to listen: %v", err) + } + grpcServer := grpc.NewServer() + encoding.RegisterCodec(flatbuffers.FlatbuffersCodec{}) + models.RegisterGreeterServer(grpcServer, newServer()) + if err := grpcServer.Serve(lis); err != nil { + fmt.Print(err) + panic(err) + } +} diff --git a/grpc/examples/greeter.fbs b/grpc/examples/greeter.fbs new file mode 100644 index 00000000..651fb677 --- /dev/null +++ b/grpc/examples/greeter.fbs @@ -0,0 +1,14 @@ +namespace models; + +table HelloReply { + message:string; +} + +table HelloRequest { + name:string; +} + +rpc_service Greeter { + SayHello(HelloRequest):HelloReply; + SayManyHellos(HelloRequest):HelloReply (streaming: "server"); +} |