├── .gitignore ├── .vscode └── settings.json ├── Dockerfile ├── README.md ├── cmd ├── client │ └── client.go └── server │ └── server.go ├── docker-compose.yaml ├── go.mod ├── go.sum ├── pb ├── user.pb.go └── user_grpc.pb.go ├── proto └── user.proto └── services └── user.go /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "go.inferGopath": false 3 | } -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.18-alpine 2 | 3 | WORKDIR /go/src 4 | 5 | RUN apk update && apk add protobuf & \ 6 | go install google.golang.org/protobuf/cmd/protoc-gen-go@latest & \ 7 | go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest 8 | 9 | 10 | CMD ["tail","-f","/dev/null"] -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Exemplo de implementação de gRPC 2 | 3 | 1. Suba o container rodando: 4 | ``` 5 | docker-compose up -d 6 | ``` 7 | 8 | 2. Acesse o container: 9 | ``` 10 | docker-compose exec app sh 11 | ``` 12 | 13 | 3. Caso queira gerar novamente as stubs: 14 | ``` 15 | protoc --proto_path=proto/ proto/*.proto --plugin=$(go env GOPATH)/bin/protoc-gen-go-grpc --go-grpc_out=. --go_out=. 16 | ``` -------------------------------------------------------------------------------- /cmd/client/client.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "io" 7 | "log" 8 | "time" 9 | 10 | "github.com/codeedu/fc2-grpc/pb" 11 | "google.golang.org/grpc" 12 | ) 13 | 14 | func main() { 15 | connection, err := grpc.Dial("localhost:50051", grpc.WithInsecure()) 16 | if err != nil { 17 | log.Fatalf("Could not connect to gRPC Server: %v", err) 18 | } 19 | defer connection.Close() 20 | 21 | client := pb.NewUserServiceClient(connection) 22 | // AddUser(client) 23 | // AddUserVerbose(client) 24 | // AddUsers(client) 25 | AddUserStreamBoth(client) 26 | 27 | } 28 | 29 | func AddUser(client pb.UserServiceClient) { 30 | req := &pb.User{ 31 | Id: "0", 32 | Name: "Joao", 33 | Email: "j@j.com", 34 | } 35 | res, err := client.AddUser(context.Background(), req) 36 | if err != nil { 37 | log.Fatalf("Could not make gRPC request: %v", err) 38 | } 39 | fmt.Println(res) 40 | } 41 | 42 | func AddUserVerbose(client pb.UserServiceClient) { 43 | 44 | req := &pb.User{ 45 | Id: "0", 46 | Name: "Joao", 47 | Email: "j@j.com", 48 | } 49 | 50 | responseStream, err := client.AddUserVerbose(context.Background(), req) 51 | if err != nil { 52 | log.Fatalf("Could not make gRPC request: %v", err) 53 | } 54 | 55 | for { 56 | stream, err := responseStream.Recv() 57 | if err == io.EOF { 58 | break 59 | } 60 | if err != nil { 61 | log.Fatalf("Could not receive the msg: %v", err) 62 | } 63 | fmt.Println("Status:", stream.Status, " - ", stream.GetUser()) 64 | } 65 | } 66 | 67 | func AddUsers(client pb.UserServiceClient) { 68 | reqs := []*pb.User{ 69 | &pb.User{ 70 | Id: "w1", 71 | Name: "Wesley", 72 | Email: "wes@wes.com", 73 | }, 74 | &pb.User{ 75 | Id: "w2", 76 | Name: "Wesley 2", 77 | Email: "wes2@wes.com", 78 | }, 79 | &pb.User{ 80 | Id: "w3", 81 | Name: "Wesley 3", 82 | Email: "wes3@wes.com", 83 | }, 84 | &pb.User{ 85 | Id: "w4", 86 | Name: "Wesley 4", 87 | Email: "wes4@wes.com", 88 | }, 89 | &pb.User{ 90 | Id: "w5", 91 | Name: "Wesley 5", 92 | Email: "wes5@wes.com", 93 | }, 94 | } 95 | 96 | stream, err := client.AddUsers(context.Background()) 97 | if err != nil { 98 | log.Fatalf("Error creating request: %v", err) 99 | } 100 | 101 | for _, req := range reqs { 102 | stream.Send(req) 103 | time.Sleep(time.Second * 3) 104 | } 105 | 106 | res, err := stream.CloseAndRecv() 107 | if err != nil { 108 | log.Fatalf("Error receiving response: %v", err) 109 | } 110 | 111 | fmt.Println(res) 112 | } 113 | 114 | func AddUserStreamBoth(client pb.UserServiceClient) { 115 | 116 | stream, err := client.AddUserStreamBoth(context.Background()) 117 | if err != nil { 118 | log.Fatalf("Error creating request: %v", err) 119 | } 120 | 121 | reqs := []*pb.User{ 122 | &pb.User{ 123 | Id: "w1", 124 | Name: "Wesley", 125 | Email: "wes@wes.com", 126 | }, 127 | &pb.User{ 128 | Id: "w2", 129 | Name: "Wesley 2", 130 | Email: "wes2@wes.com", 131 | }, 132 | &pb.User{ 133 | Id: "w3", 134 | Name: "Wesley 3", 135 | Email: "wes3@wes.com", 136 | }, 137 | &pb.User{ 138 | Id: "w4", 139 | Name: "Wesley 4", 140 | Email: "wes4@wes.com", 141 | }, 142 | &pb.User{ 143 | Id: "w5", 144 | Name: "Wesley 5", 145 | Email: "wes5@wes.com", 146 | }, 147 | } 148 | 149 | wait := make(chan int) 150 | 151 | go func() { 152 | for _, req := range reqs { 153 | fmt.Println("Sending user: ", req.Name) 154 | stream.Send(req) 155 | time.Sleep(time.Second * 2) 156 | } 157 | stream.CloseSend() 158 | }() 159 | 160 | go func() { 161 | for { 162 | res, err := stream.Recv() 163 | if err == io.EOF { 164 | break 165 | } 166 | if err != nil { 167 | log.Fatalf("Error receiving data: %v", err) 168 | break 169 | } 170 | fmt.Printf("Recebendo user %v com status: %v\n", res.GetUser().GetName(), res.GetStatus()) 171 | } 172 | close(wait) 173 | }() 174 | 175 | <-wait 176 | 177 | } 178 | -------------------------------------------------------------------------------- /cmd/server/server.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "net" 6 | 7 | "github.com/codeedu/fc2-grpc/pb" 8 | "github.com/codeedu/fc2-grpc/services" 9 | "google.golang.org/grpc" 10 | "google.golang.org/grpc/reflection" 11 | ) 12 | 13 | func main() { 14 | 15 | lis, err := net.Listen("tcp", "localhost:50051") 16 | if err != nil { 17 | log.Fatalf("Could not connect: %v", err) 18 | } 19 | 20 | grpcServer := grpc.NewServer() 21 | pb.RegisterUserServiceServer(grpcServer, &services.UserService{}) 22 | reflection.Register(grpcServer) 23 | 24 | if err := grpcServer.Serve(lis); err != nil { 25 | log.Fatalf("Could not serve: %v", err) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | services: 4 | app: 5 | build: . 6 | ports: 7 | - 50021:50021 8 | volumes: 9 | - .:/go/src 10 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/codeedu/fc2-grpc 2 | 3 | go 1.15 4 | 5 | require ( 6 | github.com/golang/protobuf v1.4.3 // indirect 7 | github.com/google/go-cmp v0.5.4 // indirect 8 | golang.org/x/net v0.0.0-20201216054612-986b41b23924 // indirect 9 | golang.org/x/sys v0.0.0-20201221093633-bc327ba9c2f0 // indirect 10 | golang.org/x/text v0.3.4 // indirect 11 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect 12 | google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d // indirect 13 | google.golang.org/grpc v1.34.0 14 | google.golang.org/protobuf v1.25.0 15 | ) 16 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 2 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 3 | github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= 4 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= 5 | github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= 6 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 7 | github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= 8 | github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= 9 | github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= 10 | github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= 11 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= 12 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 13 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 14 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 15 | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= 16 | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= 17 | github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= 18 | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= 19 | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= 20 | github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= 21 | github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 22 | github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= 23 | github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 24 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= 25 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 26 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 27 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 28 | github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 29 | github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= 30 | github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 31 | github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 32 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 33 | github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 34 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 35 | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 36 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 37 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 38 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 39 | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= 40 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 41 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 42 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 43 | golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 44 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 45 | golang.org/x/net v0.0.0-20201216054612-986b41b23924 h1:QsnDpLLOKwHBBDa8nDws4DYNc/ryVW2vCpxCs09d4PY= 46 | golang.org/x/net v0.0.0-20201216054612-986b41b23924/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 47 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 48 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 49 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 50 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 51 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 52 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 53 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 54 | golang.org/x/sys v0.0.0-20201221093633-bc327ba9c2f0 h1:n+DPcgTwkgWzIFpLmoimYR2K2b0Ga5+Os4kayIN0vGo= 55 | golang.org/x/sys v0.0.0-20201221093633-bc327ba9c2f0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 56 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 57 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 58 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 59 | golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc= 60 | golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 61 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 62 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 63 | golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= 64 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 65 | golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 66 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 67 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= 68 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 69 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 70 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 71 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 72 | google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 73 | google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= 74 | google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d h1:HV9Z9qMhQEsdlvxNFELgQ11RkMzO3CMkjEySjCtuLes= 75 | google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 76 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= 77 | google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= 78 | google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= 79 | google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 80 | google.golang.org/grpc v1.34.0 h1:raiipEjMOIC/TO2AvyTxP25XFdLxNIBwzDh3FM3XztI= 81 | google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= 82 | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= 83 | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= 84 | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= 85 | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= 86 | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= 87 | google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 88 | google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 89 | google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 90 | google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= 91 | google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= 92 | google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= 93 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 94 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 95 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 96 | honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 97 | -------------------------------------------------------------------------------- /pb/user.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // versions: 3 | // protoc-gen-go v1.28.0 4 | // protoc v3.18.1 5 | // source: user.proto 6 | 7 | package pb 8 | 9 | import ( 10 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 11 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 12 | reflect "reflect" 13 | sync "sync" 14 | ) 15 | 16 | const ( 17 | // Verify that this generated code is sufficiently up-to-date. 18 | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) 19 | // Verify that runtime/protoimpl is sufficiently up-to-date. 20 | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) 21 | ) 22 | 23 | type User struct { 24 | state protoimpl.MessageState 25 | sizeCache protoimpl.SizeCache 26 | unknownFields protoimpl.UnknownFields 27 | 28 | Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` 29 | Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` 30 | Email string `protobuf:"bytes,3,opt,name=email,proto3" json:"email,omitempty"` 31 | } 32 | 33 | func (x *User) Reset() { 34 | *x = User{} 35 | if protoimpl.UnsafeEnabled { 36 | mi := &file_user_proto_msgTypes[0] 37 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 38 | ms.StoreMessageInfo(mi) 39 | } 40 | } 41 | 42 | func (x *User) String() string { 43 | return protoimpl.X.MessageStringOf(x) 44 | } 45 | 46 | func (*User) ProtoMessage() {} 47 | 48 | func (x *User) ProtoReflect() protoreflect.Message { 49 | mi := &file_user_proto_msgTypes[0] 50 | if protoimpl.UnsafeEnabled && x != nil { 51 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 52 | if ms.LoadMessageInfo() == nil { 53 | ms.StoreMessageInfo(mi) 54 | } 55 | return ms 56 | } 57 | return mi.MessageOf(x) 58 | } 59 | 60 | // Deprecated: Use User.ProtoReflect.Descriptor instead. 61 | func (*User) Descriptor() ([]byte, []int) { 62 | return file_user_proto_rawDescGZIP(), []int{0} 63 | } 64 | 65 | func (x *User) GetId() string { 66 | if x != nil { 67 | return x.Id 68 | } 69 | return "" 70 | } 71 | 72 | func (x *User) GetName() string { 73 | if x != nil { 74 | return x.Name 75 | } 76 | return "" 77 | } 78 | 79 | func (x *User) GetEmail() string { 80 | if x != nil { 81 | return x.Email 82 | } 83 | return "" 84 | } 85 | 86 | type UserResultStream struct { 87 | state protoimpl.MessageState 88 | sizeCache protoimpl.SizeCache 89 | unknownFields protoimpl.UnknownFields 90 | 91 | Status string `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"` 92 | User *User `protobuf:"bytes,2,opt,name=user,proto3" json:"user,omitempty"` 93 | } 94 | 95 | func (x *UserResultStream) Reset() { 96 | *x = UserResultStream{} 97 | if protoimpl.UnsafeEnabled { 98 | mi := &file_user_proto_msgTypes[1] 99 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 100 | ms.StoreMessageInfo(mi) 101 | } 102 | } 103 | 104 | func (x *UserResultStream) String() string { 105 | return protoimpl.X.MessageStringOf(x) 106 | } 107 | 108 | func (*UserResultStream) ProtoMessage() {} 109 | 110 | func (x *UserResultStream) ProtoReflect() protoreflect.Message { 111 | mi := &file_user_proto_msgTypes[1] 112 | if protoimpl.UnsafeEnabled && x != nil { 113 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 114 | if ms.LoadMessageInfo() == nil { 115 | ms.StoreMessageInfo(mi) 116 | } 117 | return ms 118 | } 119 | return mi.MessageOf(x) 120 | } 121 | 122 | // Deprecated: Use UserResultStream.ProtoReflect.Descriptor instead. 123 | func (*UserResultStream) Descriptor() ([]byte, []int) { 124 | return file_user_proto_rawDescGZIP(), []int{1} 125 | } 126 | 127 | func (x *UserResultStream) GetStatus() string { 128 | if x != nil { 129 | return x.Status 130 | } 131 | return "" 132 | } 133 | 134 | func (x *UserResultStream) GetUser() *User { 135 | if x != nil { 136 | return x.User 137 | } 138 | return nil 139 | } 140 | 141 | type Users struct { 142 | state protoimpl.MessageState 143 | sizeCache protoimpl.SizeCache 144 | unknownFields protoimpl.UnknownFields 145 | 146 | User []*User `protobuf:"bytes,1,rep,name=user,proto3" json:"user,omitempty"` 147 | } 148 | 149 | func (x *Users) Reset() { 150 | *x = Users{} 151 | if protoimpl.UnsafeEnabled { 152 | mi := &file_user_proto_msgTypes[2] 153 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 154 | ms.StoreMessageInfo(mi) 155 | } 156 | } 157 | 158 | func (x *Users) String() string { 159 | return protoimpl.X.MessageStringOf(x) 160 | } 161 | 162 | func (*Users) ProtoMessage() {} 163 | 164 | func (x *Users) ProtoReflect() protoreflect.Message { 165 | mi := &file_user_proto_msgTypes[2] 166 | if protoimpl.UnsafeEnabled && x != nil { 167 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 168 | if ms.LoadMessageInfo() == nil { 169 | ms.StoreMessageInfo(mi) 170 | } 171 | return ms 172 | } 173 | return mi.MessageOf(x) 174 | } 175 | 176 | // Deprecated: Use Users.ProtoReflect.Descriptor instead. 177 | func (*Users) Descriptor() ([]byte, []int) { 178 | return file_user_proto_rawDescGZIP(), []int{2} 179 | } 180 | 181 | func (x *Users) GetUser() []*User { 182 | if x != nil { 183 | return x.User 184 | } 185 | return nil 186 | } 187 | 188 | var File_user_proto protoreflect.FileDescriptor 189 | 190 | var file_user_proto_rawDesc = []byte{ 191 | 0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, 192 | 0x22, 0x40, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 193 | 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 194 | 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 195 | 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 196 | 0x69, 0x6c, 0x22, 0x48, 0x0a, 0x10, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 197 | 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 198 | 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1c, 199 | 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x70, 200 | 0x62, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x25, 0x0a, 0x05, 201 | 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x1c, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 202 | 0x03, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 203 | 0x73, 0x65, 0x72, 0x32, 0xbc, 0x01, 0x0a, 0x0b, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 204 | 0x69, 0x63, 0x65, 0x12, 0x1d, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x55, 0x73, 0x65, 0x72, 0x12, 0x08, 205 | 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x1a, 0x08, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x73, 206 | 0x65, 0x72, 0x12, 0x32, 0x0a, 0x0e, 0x41, 0x64, 0x64, 0x55, 0x73, 0x65, 0x72, 0x56, 0x65, 0x72, 207 | 0x62, 0x6f, 0x73, 0x65, 0x12, 0x08, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x1a, 0x14, 208 | 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x53, 0x74, 209 | 0x72, 0x65, 0x61, 0x6d, 0x30, 0x01, 0x12, 0x21, 0x0a, 0x08, 0x41, 0x64, 0x64, 0x55, 0x73, 0x65, 210 | 0x72, 0x73, 0x12, 0x08, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x1a, 0x09, 0x2e, 0x70, 211 | 0x62, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x73, 0x28, 0x01, 0x12, 0x37, 0x0a, 0x11, 0x41, 0x64, 0x64, 212 | 0x55, 0x73, 0x65, 0x72, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x42, 0x6f, 0x74, 0x68, 0x12, 0x08, 213 | 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x1a, 0x14, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x73, 214 | 0x65, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x28, 0x01, 215 | 0x30, 0x01, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 216 | 0x6f, 0x33, 217 | } 218 | 219 | var ( 220 | file_user_proto_rawDescOnce sync.Once 221 | file_user_proto_rawDescData = file_user_proto_rawDesc 222 | ) 223 | 224 | func file_user_proto_rawDescGZIP() []byte { 225 | file_user_proto_rawDescOnce.Do(func() { 226 | file_user_proto_rawDescData = protoimpl.X.CompressGZIP(file_user_proto_rawDescData) 227 | }) 228 | return file_user_proto_rawDescData 229 | } 230 | 231 | var file_user_proto_msgTypes = make([]protoimpl.MessageInfo, 3) 232 | var file_user_proto_goTypes = []interface{}{ 233 | (*User)(nil), // 0: pb.User 234 | (*UserResultStream)(nil), // 1: pb.UserResultStream 235 | (*Users)(nil), // 2: pb.Users 236 | } 237 | var file_user_proto_depIdxs = []int32{ 238 | 0, // 0: pb.UserResultStream.user:type_name -> pb.User 239 | 0, // 1: pb.Users.user:type_name -> pb.User 240 | 0, // 2: pb.UserService.AddUser:input_type -> pb.User 241 | 0, // 3: pb.UserService.AddUserVerbose:input_type -> pb.User 242 | 0, // 4: pb.UserService.AddUsers:input_type -> pb.User 243 | 0, // 5: pb.UserService.AddUserStreamBoth:input_type -> pb.User 244 | 0, // 6: pb.UserService.AddUser:output_type -> pb.User 245 | 1, // 7: pb.UserService.AddUserVerbose:output_type -> pb.UserResultStream 246 | 2, // 8: pb.UserService.AddUsers:output_type -> pb.Users 247 | 1, // 9: pb.UserService.AddUserStreamBoth:output_type -> pb.UserResultStream 248 | 6, // [6:10] is the sub-list for method output_type 249 | 2, // [2:6] is the sub-list for method input_type 250 | 2, // [2:2] is the sub-list for extension type_name 251 | 2, // [2:2] is the sub-list for extension extendee 252 | 0, // [0:2] is the sub-list for field type_name 253 | } 254 | 255 | func init() { file_user_proto_init() } 256 | func file_user_proto_init() { 257 | if File_user_proto != nil { 258 | return 259 | } 260 | if !protoimpl.UnsafeEnabled { 261 | file_user_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { 262 | switch v := v.(*User); i { 263 | case 0: 264 | return &v.state 265 | case 1: 266 | return &v.sizeCache 267 | case 2: 268 | return &v.unknownFields 269 | default: 270 | return nil 271 | } 272 | } 273 | file_user_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { 274 | switch v := v.(*UserResultStream); i { 275 | case 0: 276 | return &v.state 277 | case 1: 278 | return &v.sizeCache 279 | case 2: 280 | return &v.unknownFields 281 | default: 282 | return nil 283 | } 284 | } 285 | file_user_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { 286 | switch v := v.(*Users); i { 287 | case 0: 288 | return &v.state 289 | case 1: 290 | return &v.sizeCache 291 | case 2: 292 | return &v.unknownFields 293 | default: 294 | return nil 295 | } 296 | } 297 | } 298 | type x struct{} 299 | out := protoimpl.TypeBuilder{ 300 | File: protoimpl.DescBuilder{ 301 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 302 | RawDescriptor: file_user_proto_rawDesc, 303 | NumEnums: 0, 304 | NumMessages: 3, 305 | NumExtensions: 0, 306 | NumServices: 1, 307 | }, 308 | GoTypes: file_user_proto_goTypes, 309 | DependencyIndexes: file_user_proto_depIdxs, 310 | MessageInfos: file_user_proto_msgTypes, 311 | }.Build() 312 | File_user_proto = out.File 313 | file_user_proto_rawDesc = nil 314 | file_user_proto_goTypes = nil 315 | file_user_proto_depIdxs = nil 316 | } 317 | -------------------------------------------------------------------------------- /pb/user_grpc.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go-grpc. DO NOT EDIT. 2 | // versions: 3 | // - protoc-gen-go-grpc v1.2.0 4 | // - protoc v3.18.1 5 | // source: user.proto 6 | 7 | package pb 8 | 9 | import ( 10 | context "context" 11 | grpc "google.golang.org/grpc" 12 | codes "google.golang.org/grpc/codes" 13 | status "google.golang.org/grpc/status" 14 | ) 15 | 16 | // This is a compile-time assertion to ensure that this generated file 17 | // is compatible with the grpc package it is being compiled against. 18 | // Requires gRPC-Go v1.32.0 or later. 19 | const _ = grpc.SupportPackageIsVersion7 20 | 21 | // UserServiceClient is the client API for UserService service. 22 | // 23 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. 24 | type UserServiceClient interface { 25 | AddUser(ctx context.Context, in *User, opts ...grpc.CallOption) (*User, error) 26 | AddUserVerbose(ctx context.Context, in *User, opts ...grpc.CallOption) (UserService_AddUserVerboseClient, error) 27 | AddUsers(ctx context.Context, opts ...grpc.CallOption) (UserService_AddUsersClient, error) 28 | AddUserStreamBoth(ctx context.Context, opts ...grpc.CallOption) (UserService_AddUserStreamBothClient, error) 29 | } 30 | 31 | type userServiceClient struct { 32 | cc grpc.ClientConnInterface 33 | } 34 | 35 | func NewUserServiceClient(cc grpc.ClientConnInterface) UserServiceClient { 36 | return &userServiceClient{cc} 37 | } 38 | 39 | func (c *userServiceClient) AddUser(ctx context.Context, in *User, opts ...grpc.CallOption) (*User, error) { 40 | out := new(User) 41 | err := c.cc.Invoke(ctx, "/pb.UserService/AddUser", in, out, opts...) 42 | if err != nil { 43 | return nil, err 44 | } 45 | return out, nil 46 | } 47 | 48 | func (c *userServiceClient) AddUserVerbose(ctx context.Context, in *User, opts ...grpc.CallOption) (UserService_AddUserVerboseClient, error) { 49 | stream, err := c.cc.NewStream(ctx, &UserService_ServiceDesc.Streams[0], "/pb.UserService/AddUserVerbose", opts...) 50 | if err != nil { 51 | return nil, err 52 | } 53 | x := &userServiceAddUserVerboseClient{stream} 54 | if err := x.ClientStream.SendMsg(in); err != nil { 55 | return nil, err 56 | } 57 | if err := x.ClientStream.CloseSend(); err != nil { 58 | return nil, err 59 | } 60 | return x, nil 61 | } 62 | 63 | type UserService_AddUserVerboseClient interface { 64 | Recv() (*UserResultStream, error) 65 | grpc.ClientStream 66 | } 67 | 68 | type userServiceAddUserVerboseClient struct { 69 | grpc.ClientStream 70 | } 71 | 72 | func (x *userServiceAddUserVerboseClient) Recv() (*UserResultStream, error) { 73 | m := new(UserResultStream) 74 | if err := x.ClientStream.RecvMsg(m); err != nil { 75 | return nil, err 76 | } 77 | return m, nil 78 | } 79 | 80 | func (c *userServiceClient) AddUsers(ctx context.Context, opts ...grpc.CallOption) (UserService_AddUsersClient, error) { 81 | stream, err := c.cc.NewStream(ctx, &UserService_ServiceDesc.Streams[1], "/pb.UserService/AddUsers", opts...) 82 | if err != nil { 83 | return nil, err 84 | } 85 | x := &userServiceAddUsersClient{stream} 86 | return x, nil 87 | } 88 | 89 | type UserService_AddUsersClient interface { 90 | Send(*User) error 91 | CloseAndRecv() (*Users, error) 92 | grpc.ClientStream 93 | } 94 | 95 | type userServiceAddUsersClient struct { 96 | grpc.ClientStream 97 | } 98 | 99 | func (x *userServiceAddUsersClient) Send(m *User) error { 100 | return x.ClientStream.SendMsg(m) 101 | } 102 | 103 | func (x *userServiceAddUsersClient) CloseAndRecv() (*Users, error) { 104 | if err := x.ClientStream.CloseSend(); err != nil { 105 | return nil, err 106 | } 107 | m := new(Users) 108 | if err := x.ClientStream.RecvMsg(m); err != nil { 109 | return nil, err 110 | } 111 | return m, nil 112 | } 113 | 114 | func (c *userServiceClient) AddUserStreamBoth(ctx context.Context, opts ...grpc.CallOption) (UserService_AddUserStreamBothClient, error) { 115 | stream, err := c.cc.NewStream(ctx, &UserService_ServiceDesc.Streams[2], "/pb.UserService/AddUserStreamBoth", opts...) 116 | if err != nil { 117 | return nil, err 118 | } 119 | x := &userServiceAddUserStreamBothClient{stream} 120 | return x, nil 121 | } 122 | 123 | type UserService_AddUserStreamBothClient interface { 124 | Send(*User) error 125 | Recv() (*UserResultStream, error) 126 | grpc.ClientStream 127 | } 128 | 129 | type userServiceAddUserStreamBothClient struct { 130 | grpc.ClientStream 131 | } 132 | 133 | func (x *userServiceAddUserStreamBothClient) Send(m *User) error { 134 | return x.ClientStream.SendMsg(m) 135 | } 136 | 137 | func (x *userServiceAddUserStreamBothClient) Recv() (*UserResultStream, error) { 138 | m := new(UserResultStream) 139 | if err := x.ClientStream.RecvMsg(m); err != nil { 140 | return nil, err 141 | } 142 | return m, nil 143 | } 144 | 145 | // UserServiceServer is the server API for UserService service. 146 | // All implementations must embed UnimplementedUserServiceServer 147 | // for forward compatibility 148 | type UserServiceServer interface { 149 | AddUser(context.Context, *User) (*User, error) 150 | AddUserVerbose(*User, UserService_AddUserVerboseServer) error 151 | AddUsers(UserService_AddUsersServer) error 152 | AddUserStreamBoth(UserService_AddUserStreamBothServer) error 153 | mustEmbedUnimplementedUserServiceServer() 154 | } 155 | 156 | // UnimplementedUserServiceServer must be embedded to have forward compatible implementations. 157 | type UnimplementedUserServiceServer struct { 158 | } 159 | 160 | func (UnimplementedUserServiceServer) AddUser(context.Context, *User) (*User, error) { 161 | return nil, status.Errorf(codes.Unimplemented, "method AddUser not implemented") 162 | } 163 | func (UnimplementedUserServiceServer) AddUserVerbose(*User, UserService_AddUserVerboseServer) error { 164 | return status.Errorf(codes.Unimplemented, "method AddUserVerbose not implemented") 165 | } 166 | func (UnimplementedUserServiceServer) AddUsers(UserService_AddUsersServer) error { 167 | return status.Errorf(codes.Unimplemented, "method AddUsers not implemented") 168 | } 169 | func (UnimplementedUserServiceServer) AddUserStreamBoth(UserService_AddUserStreamBothServer) error { 170 | return status.Errorf(codes.Unimplemented, "method AddUserStreamBoth not implemented") 171 | } 172 | func (UnimplementedUserServiceServer) mustEmbedUnimplementedUserServiceServer() {} 173 | 174 | // UnsafeUserServiceServer may be embedded to opt out of forward compatibility for this service. 175 | // Use of this interface is not recommended, as added methods to UserServiceServer will 176 | // result in compilation errors. 177 | type UnsafeUserServiceServer interface { 178 | mustEmbedUnimplementedUserServiceServer() 179 | } 180 | 181 | func RegisterUserServiceServer(s grpc.ServiceRegistrar, srv UserServiceServer) { 182 | s.RegisterService(&UserService_ServiceDesc, srv) 183 | } 184 | 185 | func _UserService_AddUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 186 | in := new(User) 187 | if err := dec(in); err != nil { 188 | return nil, err 189 | } 190 | if interceptor == nil { 191 | return srv.(UserServiceServer).AddUser(ctx, in) 192 | } 193 | info := &grpc.UnaryServerInfo{ 194 | Server: srv, 195 | FullMethod: "/pb.UserService/AddUser", 196 | } 197 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 198 | return srv.(UserServiceServer).AddUser(ctx, req.(*User)) 199 | } 200 | return interceptor(ctx, in, info, handler) 201 | } 202 | 203 | func _UserService_AddUserVerbose_Handler(srv interface{}, stream grpc.ServerStream) error { 204 | m := new(User) 205 | if err := stream.RecvMsg(m); err != nil { 206 | return err 207 | } 208 | return srv.(UserServiceServer).AddUserVerbose(m, &userServiceAddUserVerboseServer{stream}) 209 | } 210 | 211 | type UserService_AddUserVerboseServer interface { 212 | Send(*UserResultStream) error 213 | grpc.ServerStream 214 | } 215 | 216 | type userServiceAddUserVerboseServer struct { 217 | grpc.ServerStream 218 | } 219 | 220 | func (x *userServiceAddUserVerboseServer) Send(m *UserResultStream) error { 221 | return x.ServerStream.SendMsg(m) 222 | } 223 | 224 | func _UserService_AddUsers_Handler(srv interface{}, stream grpc.ServerStream) error { 225 | return srv.(UserServiceServer).AddUsers(&userServiceAddUsersServer{stream}) 226 | } 227 | 228 | type UserService_AddUsersServer interface { 229 | SendAndClose(*Users) error 230 | Recv() (*User, error) 231 | grpc.ServerStream 232 | } 233 | 234 | type userServiceAddUsersServer struct { 235 | grpc.ServerStream 236 | } 237 | 238 | func (x *userServiceAddUsersServer) SendAndClose(m *Users) error { 239 | return x.ServerStream.SendMsg(m) 240 | } 241 | 242 | func (x *userServiceAddUsersServer) Recv() (*User, error) { 243 | m := new(User) 244 | if err := x.ServerStream.RecvMsg(m); err != nil { 245 | return nil, err 246 | } 247 | return m, nil 248 | } 249 | 250 | func _UserService_AddUserStreamBoth_Handler(srv interface{}, stream grpc.ServerStream) error { 251 | return srv.(UserServiceServer).AddUserStreamBoth(&userServiceAddUserStreamBothServer{stream}) 252 | } 253 | 254 | type UserService_AddUserStreamBothServer interface { 255 | Send(*UserResultStream) error 256 | Recv() (*User, error) 257 | grpc.ServerStream 258 | } 259 | 260 | type userServiceAddUserStreamBothServer struct { 261 | grpc.ServerStream 262 | } 263 | 264 | func (x *userServiceAddUserStreamBothServer) Send(m *UserResultStream) error { 265 | return x.ServerStream.SendMsg(m) 266 | } 267 | 268 | func (x *userServiceAddUserStreamBothServer) Recv() (*User, error) { 269 | m := new(User) 270 | if err := x.ServerStream.RecvMsg(m); err != nil { 271 | return nil, err 272 | } 273 | return m, nil 274 | } 275 | 276 | // UserService_ServiceDesc is the grpc.ServiceDesc for UserService service. 277 | // It's only intended for direct use with grpc.RegisterService, 278 | // and not to be introspected or modified (even as a copy) 279 | var UserService_ServiceDesc = grpc.ServiceDesc{ 280 | ServiceName: "pb.UserService", 281 | HandlerType: (*UserServiceServer)(nil), 282 | Methods: []grpc.MethodDesc{ 283 | { 284 | MethodName: "AddUser", 285 | Handler: _UserService_AddUser_Handler, 286 | }, 287 | }, 288 | Streams: []grpc.StreamDesc{ 289 | { 290 | StreamName: "AddUserVerbose", 291 | Handler: _UserService_AddUserVerbose_Handler, 292 | ServerStreams: true, 293 | }, 294 | { 295 | StreamName: "AddUsers", 296 | Handler: _UserService_AddUsers_Handler, 297 | ClientStreams: true, 298 | }, 299 | { 300 | StreamName: "AddUserStreamBoth", 301 | Handler: _UserService_AddUserStreamBoth_Handler, 302 | ServerStreams: true, 303 | ClientStreams: true, 304 | }, 305 | }, 306 | Metadata: "user.proto", 307 | } 308 | -------------------------------------------------------------------------------- /proto/user.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package pb; 3 | option go_package = "./pb"; 4 | 5 | message User { 6 | string id = 1; 7 | string name = 2; 8 | string email = 3; 9 | } 10 | 11 | message UserResultStream { 12 | string status = 1; 13 | User user = 2; 14 | } 15 | 16 | message Users { 17 | repeated User user = 1; 18 | } 19 | 20 | service UserService { 21 | rpc AddUser (User) returns (User); 22 | rpc AddUserVerbose (User) returns (stream UserResultStream); 23 | rpc AddUsers(stream User) returns (Users); 24 | rpc AddUserStreamBoth (stream User) returns (stream UserResultStream); 25 | } -------------------------------------------------------------------------------- /services/user.go: -------------------------------------------------------------------------------- 1 | package services 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "io" 7 | "log" 8 | "time" 9 | 10 | "github.com/codeedu/fc2-grpc/pb" 11 | ) 12 | 13 | // type UserServiceServer interface { 14 | // AddUser(context.Context, *User) (*User, error) 15 | // mustEmbedUnimplementedUserServiceServer() 16 | // AddUserVerbose(ctx context.Context, in *User, opts ...grpc.CallOption) (UserService_AddUserVerboseClient, error) 17 | // AddUsers(ctx context.Context, opts ...grpc.CallOption) (UserService_AddUsersClient, error) 18 | // } 19 | 20 | type UserService struct { 21 | pb.UnimplementedUserServiceServer 22 | } 23 | 24 | func NewUserService() *UserService { 25 | return &UserService{} 26 | } 27 | 28 | func (*UserService) AddUser(ctx context.Context, req *pb.User) (*pb.User, error) { 29 | 30 | // Insert - Database 31 | fmt.Println(req.Name) 32 | 33 | return &pb.User{ 34 | Id: "123", 35 | Name: req.GetName(), 36 | Email: req.GetEmail(), 37 | }, nil 38 | } 39 | 40 | func (*UserService) AddUserVerbose(req *pb.User, stream pb.UserService_AddUserVerboseServer) error { 41 | 42 | stream.Send(&pb.UserResultStream{ 43 | Status: "Init", 44 | User: &pb.User{}, 45 | }) 46 | 47 | time.Sleep(time.Second * 3) 48 | 49 | stream.Send(&pb.UserResultStream{ 50 | Status: "Inserting", 51 | User: &pb.User{}, 52 | }) 53 | 54 | time.Sleep(time.Second * 3) 55 | 56 | stream.Send(&pb.UserResultStream{ 57 | Status: "User has been inserted", 58 | User: &pb.User{ 59 | Id: "123", 60 | Name: req.GetName(), 61 | Email: req.GetEmail(), 62 | }, 63 | }) 64 | 65 | time.Sleep(time.Second * 3) 66 | 67 | stream.Send(&pb.UserResultStream{ 68 | Status: "Completed", 69 | User: &pb.User{ 70 | Id: "123", 71 | Name: req.GetName(), 72 | Email: req.GetEmail(), 73 | }, 74 | }) 75 | 76 | time.Sleep(time.Second * 3) 77 | 78 | return nil 79 | 80 | } 81 | 82 | func (*UserService) AddUsers(stream pb.UserService_AddUsersServer) error { 83 | 84 | users := []*pb.User{} 85 | 86 | for { 87 | req, err := stream.Recv() 88 | if err == io.EOF { 89 | return stream.SendAndClose(&pb.Users{ 90 | User: users, 91 | }) 92 | } 93 | if err != nil { 94 | log.Fatalf("Error receiving stream: %v", err) 95 | } 96 | 97 | users = append(users, &pb.User{ 98 | Id: req.GetId(), 99 | Name: req.GetName(), 100 | Email: req.GetEmail(), 101 | }) 102 | fmt.Println("Adding", req.GetName()) 103 | 104 | } 105 | 106 | } 107 | 108 | func (*UserService) AddUserStreamBoth(stream pb.UserService_AddUserStreamBothServer) error { 109 | 110 | for { 111 | req, err := stream.Recv() 112 | if err == io.EOF { 113 | return nil 114 | } 115 | if err != nil { 116 | log.Fatalf("Error receiving stream from the client: %v", err) 117 | } 118 | 119 | err = stream.Send(&pb.UserResultStream{ 120 | Status: "Added", 121 | User: req, 122 | }) 123 | if err != nil { 124 | log.Fatalf("Error sending stream to the client: %v", err) 125 | } 126 | } 127 | } 128 | --------------------------------------------------------------------------------