mirror of https://github.com/dapr/go-sdk.git
Add example for dapr grpc proxy mode (#414)
* Add example for dapr grpc proxy mode Signed-off-by: hunter007 <wentao79@gmail.com> * Modify README.md Signed-off-by: hunter007 <wentao79@gmail.com> --------- Signed-off-by: hunter007 <wentao79@gmail.com>
This commit is contained in:
parent
10b832f741
commit
effc2f0d3c
|
|
@ -90,6 +90,7 @@ jobs:
|
|||
- name: Check Examples
|
||||
run: |
|
||||
cd examples
|
||||
./validate.sh grpc-service
|
||||
./validate.sh configuration
|
||||
./validate.sh hello-world
|
||||
./validate.sh pubsub
|
||||
|
|
|
|||
4
Makefile
4
Makefile
|
|
@ -19,7 +19,7 @@ test:
|
|||
./...
|
||||
|
||||
.PHONY: spell
|
||||
spell: ## Checks spelling across the entire project
|
||||
spell: ## Checks spelling across the entire project
|
||||
@command -v misspell > /dev/null 2>&1 || (cd tools && go get github.com/client9/misspell/cmd/misspell)
|
||||
@misspell -locale US -error go=golang client/**/* examples/**/* service/**/* actor/**/* .
|
||||
|
||||
|
|
@ -34,7 +34,7 @@ lint: ## Lints the entire project
|
|||
golangci-lint run --timeout=3m
|
||||
|
||||
.PHONY: tag
|
||||
tag: ## Creates release tag
|
||||
tag: ## Creates release tag
|
||||
git tag $(RELEASE_VERSION)
|
||||
git push origin $(RELEASE_VERSION)
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
# Grpc Service Example with proxy mode
|
||||
|
||||
The `examples/grpc-service` folder contains a Dapr enabled `server` app and a `client` app that uses this SDK to invoke grpc methos via grpc stub, The `server` app is available as gRPC. The `client` app can target either one of these for service to service and binding invocations.
|
||||
|
||||
|
||||
## Step
|
||||
|
||||
### Prepare
|
||||
|
||||
- Dapr installed
|
||||
|
||||
### Run server as a dapr app
|
||||
|
||||
<!-- STEP
|
||||
name: Run grpc server with dapr proxy mode
|
||||
output_match_mode: substring
|
||||
expected_stdout_lines:
|
||||
- 'Received: Dapr'
|
||||
background: true
|
||||
sleep: 15
|
||||
-->
|
||||
|
||||
```bash
|
||||
dapr run --app-id grpc-server \
|
||||
--app-port 50051 \
|
||||
--app-protocol grpc \
|
||||
--dapr-grpc-port 50007 \
|
||||
go run ./server/main.go
|
||||
```
|
||||
|
||||
<!-- END_STEP -->
|
||||
|
||||
### Run grpc client
|
||||
|
||||
<!-- STEP
|
||||
name: Run grpc client
|
||||
expected_stdout_lines:
|
||||
- 'Greeting: Hello Dapr'
|
||||
output_match_mode: substring
|
||||
background: true
|
||||
sleep: 15
|
||||
-->
|
||||
|
||||
```bash
|
||||
dapr run --app-id grpc-client \
|
||||
go run ./client/main.go
|
||||
```
|
||||
|
||||
<!-- END_STEP -->
|
||||
|
||||
### Cleanup
|
||||
|
||||
<!-- STEP
|
||||
expected_stdout_lines:
|
||||
- '✅ app stopped successfully: grpc-server'
|
||||
expected_stderr_lines:
|
||||
name: Shutdown dapr
|
||||
-->
|
||||
|
||||
```bash
|
||||
dapr stop --app-id grpc-server
|
||||
```
|
||||
|
||||
<!-- END_STEP -->
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
pb "google.golang.org/grpc/examples/helloworld/helloworld"
|
||||
"google.golang.org/grpc/metadata"
|
||||
)
|
||||
|
||||
const (
|
||||
address = "localhost:50007"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Set up a connection to the server.
|
||||
conn, err := grpc.Dial(address, grpc.WithInsecure(), grpc.WithBlock())
|
||||
if err != nil {
|
||||
log.Fatalf("did not connect: %v", err)
|
||||
}
|
||||
defer conn.Close()
|
||||
c := pb.NewGreeterClient(conn)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*2)
|
||||
defer cancel()
|
||||
|
||||
ctx = metadata.AppendToOutgoingContext(ctx, "dapr-app-id", "grpc-server")
|
||||
r, err := c.SayHello(ctx, &pb.HelloRequest{Name: "Dapr"})
|
||||
if err != nil {
|
||||
log.Fatalf("could not greet: %v", err)
|
||||
}
|
||||
|
||||
log.Printf("Greeting: %s", r.GetMessage())
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
module github.com/dapr/go-sdk/examples/grpc-service
|
||||
|
||||
go 1.19
|
||||
|
||||
replace github.com/dapr/go-sdk => ../../
|
||||
|
||||
require (
|
||||
github.com/dapr/go-sdk v0.0.0-00010101000000-000000000000
|
||||
google.golang.org/grpc v1.55.0
|
||||
google.golang.org/grpc/examples v0.0.0-20230602173802-c9d3ea567325
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
golang.org/x/net v0.10.0 // indirect
|
||||
golang.org/x/sys v0.8.0 // indirect
|
||||
golang.org/x/text v0.9.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
)
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY=
|
||||
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 h1:0nDDozoAU19Qb2HwhXadU8OcsiO/09cnTqhUtq2MEOM=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA=
|
||||
google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag=
|
||||
google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8=
|
||||
google.golang.org/grpc/examples v0.0.0-20230602173802-c9d3ea567325 h1:2RthLftQfQtpQMEmkGxDGs+PAG/sVWONfKd7km4DRzM=
|
||||
google.golang.org/grpc/examples v0.0.0-20230602173802-c9d3ea567325/go.mod h1:JFf2mvgu0u96q6WJc59JQq9E9SQ6E93ML1ozmUNjW8k=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"net"
|
||||
|
||||
daprd "github.com/dapr/go-sdk/service/grpc"
|
||||
"google.golang.org/grpc"
|
||||
pb "google.golang.org/grpc/examples/helloworld/helloworld"
|
||||
)
|
||||
|
||||
const (
|
||||
port = ":50051"
|
||||
)
|
||||
|
||||
// server is used to implement helloworld.GreeterServer.
|
||||
type server struct {
|
||||
pb.UnimplementedGreeterServer
|
||||
}
|
||||
|
||||
// SayHello implements helloworld.GreeterServer
|
||||
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
|
||||
log.Printf("Received: %v", in.GetName())
|
||||
return &pb.HelloReply{Message: "Hello " + in.GetName()}, nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
lis, err := net.Listen("tcp", port)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to listen: %v", err)
|
||||
}
|
||||
|
||||
s := grpc.NewServer()
|
||||
pb.RegisterGreeterServer(s, &server{})
|
||||
daprServer := daprd.NewServiceWithGrpcServer(lis, s)
|
||||
|
||||
// start the server
|
||||
if err := daprServer.Start(); err != nil {
|
||||
log.Fatalf("server error: %v", err)
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@ Start by importing Dapr Go `service/grpc` package:
|
|||
daprd "github.com/dapr/go-sdk/service/grpc"
|
||||
```
|
||||
|
||||
## Creating and Starting Service
|
||||
## Creating and Starting Service
|
||||
|
||||
To create a gRPC Dapr service, first, create a Dapr callback instance with a specific address:
|
||||
|
||||
|
|
@ -27,6 +27,23 @@ if err != nil {
|
|||
s := daprd.NewServiceWithListener(list)
|
||||
```
|
||||
|
||||
Dapr gRPC service supports using existed gRPC server with the help of `NewServiceWithGrpcServer`. You can use `RegisterGreeterServer` to add existed gRPC service either:
|
||||
|
||||
```go
|
||||
lis, err := net.Listen("tcp", port)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to listen: %v", err)
|
||||
}
|
||||
|
||||
grpcServer := grpc.NewServer()
|
||||
|
||||
// register existed service
|
||||
// pb.RegisterGreeterServer(grpcServer, &existedGrpcServer{})
|
||||
|
||||
// new dapr grpc service
|
||||
s := daprd.NewServiceWithGrpcServer(lis, grpcServer)
|
||||
```
|
||||
|
||||
Once you create a service instance, you can "attach" to that service any number of event, binding, and service invocation logic handlers as shown below. Onces the logic is defined, you are ready to start the service:
|
||||
|
||||
```go
|
||||
|
|
@ -36,7 +53,7 @@ if err := s.Start(); err != nil {
|
|||
```
|
||||
|
||||
|
||||
## Event Handling
|
||||
## Event Handling
|
||||
|
||||
To handle events from specific topic you need to add at least one topic event handler before starting the service:
|
||||
|
||||
|
|
@ -60,9 +77,9 @@ func eventHandler(ctx context.Context, e *common.TopicEvent) (retry bool, err er
|
|||
}
|
||||
```
|
||||
|
||||
## Service Invocation Handler
|
||||
## Service Invocation Handler
|
||||
|
||||
To handle service invocations you will need to add at least one service invocation handler before starting the service:
|
||||
To handle service invocations you will need to add at least one service invocation handler before starting the service:
|
||||
|
||||
```go
|
||||
if err := s.AddServiceInvocationHandler("echo", echoHandler); err != nil {
|
||||
|
|
@ -75,7 +92,7 @@ The handler method itself can be any method with the expected signature:
|
|||
```go
|
||||
func echoHandler(ctx context.Context, in *common.InvocationEvent) (out *common.Content, err error) {
|
||||
log.Printf("echo - ContentType:%s, Verb:%s, QueryString:%s, %+v", in.ContentType, in.Verb, in.QueryString, string(in.Data))
|
||||
// do something with the invocation here
|
||||
// do something with the invocation here
|
||||
out = &common.Content{
|
||||
Data: in.Data,
|
||||
ContentType: in.ContentType,
|
||||
|
|
@ -85,9 +102,9 @@ func echoHandler(ctx context.Context, in *common.InvocationEvent) (out *common.C
|
|||
}
|
||||
```
|
||||
|
||||
## Binding Invocation Handler
|
||||
## Binding Invocation Handler
|
||||
|
||||
To handle binding invocations you will need to add at least one binding invocation handler before starting the service:
|
||||
To handle binding invocations you will need to add at least one binding invocation handler before starting the service:
|
||||
|
||||
```go
|
||||
if err := s.AddBindingInvocationHandler("run", runHandler); err != nil {
|
||||
|
|
@ -100,12 +117,12 @@ The handler method itself can be any method with the expected signature:
|
|||
```go
|
||||
func runHandler(ctx context.Context, in *common.BindingEvent) (out []byte, err error) {
|
||||
log.Printf("binding - Data:%v, Meta:%v", in.Data, in.Metadata)
|
||||
// do something with the invocation here
|
||||
// do something with the invocation here
|
||||
return nil, nil
|
||||
}
|
||||
```
|
||||
|
||||
## Templates
|
||||
## Templates
|
||||
|
||||
To accelerate your gRPC Dapr app development in Go even further you can use one of the GitHub templates integrating the gRPC Dapr callback package:
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue