[Go] Working on a go example plus fixing go grpc code (#6448)

Implemented server.go and half implemented client.go

Finishes implementation for greeter go example

Update grpc code for monster.fbs

Adds a couple of cpp methods

Adhere to gofmt standards

Adds a readme for issues with grpc
This commit is contained in:
mustiikhalil
2021-02-19 12:47:59 +03:00
committed by GitHub
parent ae603b9770
commit 0c7ae58164
19 changed files with 840 additions and 205 deletions

7
grpc/examples/README.md Normal file
View File

@@ -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"))`

18
grpc/examples/generate.sh Normal file
View File

@@ -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 ../..

2
grpc/examples/go/greeter/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
**/server
**/client

View File

@@ -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`

View File

@@ -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
)

View File

@@ -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)
}

View File

@@ -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,
},
},
}

View File

@@ -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()
}

View File

@@ -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()
}

View File

@@ -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
)

View File

@@ -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
)

View File

@@ -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)
}
}

14
grpc/examples/greeter.fbs Normal file
View File

@@ -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");
}