家具网站建设规划书,无极招聘信息网,建筑设计公司加盟分公司,营销型企业网站系统模板下载欢迎访问我的GitHubhttps://github.com/zq2599/blog_demos内容#xff1a;所有原创文章分类和汇总#xff0c;及配套源码#xff0c;涉及Java、Docker、Kubernetes、DevOPS等#xff1b;本篇概览本文《gRPC学习》系列的第三篇#xff0c;前文已准备好gRPC开发环境#xf…欢迎访问我的GitHubhttps://github.com/zq2599/blog_demos内容所有原创文章分类和汇总及配套源码涉及Java、Docker、Kubernetes、DevOPS等本篇概览本文《gRPC学习》系列的第三篇前文已准备好gRPC开发环境今天一起来开发一个服务端应用以及远程gRPC调用它的客户端今天实战的内容和步骤如下图所示源码下载如果您不想编码可以在GitHub下载所有源码地址和链接信息如下表所示这个git项目中有多个文件夹本章的应用在go-source文件夹下如下图红框所示go-source里面有多个子文件夹本篇的源码在helloworld中如下图红框环境相关接下来的开发都是在$GOPATH目录下进行的我这里的真实目录是/home/golang/gopath在/home/golang/gopath/src目录下新建helloworld目录作为接下来的实战用到的目录在完成本篇的所有开发后最终$GOPATH/src/helloworld目录下的内容如下[golangcentos7 src]$ tree helloworld/helloworld/├── client│ └── client.go├── helloworld.pb.go├── helloworld.proto└── server └── server.go2 directories, 4 files编写proto文件proto文件用来描述远程服务相关的信息如方法签名、数据结构等本篇的proto文件名为helloworld.proto位置是$GOPATH/src/helloworld内容如下// 协议类型syntax proto3;// 包名package helloworld;// 定义的服务名service Greeter { // 具体的远程服务方法 rpc SayHello (HelloRequest) returns (HelloReply) {}}// SayHello方法的入参只有一个字符串字段message HelloRequest { string name 1;}// SayHello方法的返回值只有一个字符串字段message HelloReply { string message 1;}根据proto生成go源码在helloworld.proto所在的目录执行以下命令protoc --go_outpluginsgrpc:. helloworld.proto如果helloworld.proto没有语法错误会在当前目录生成文件helloworld.pb.go这里面是工具protoc-gen-go自动生成的代码里面生成的代码在开发服务端和客户端时都会用到下面是helloworld.pb.go的代码片段作用是服务注册入参是GreeterServer是个接口由此可以推测在服务端由具体的业务代码来实现GreeterServer接口并且调用RegisterGreeterServer方法注册这样客户端远程调用的服务就可以实现业务功能了func RegisterGreeterServer(s *grpc.Server, srv GreeterServer) {s.RegisterService(_Greeter_serviceDesc, srv)}type GreeterServer interface {// 具体的远程服务方法SayHello(context.Context, *HelloRequest) (*HelloReply, error)}借助GoLand的Structure面板可以进一步观察helloworld.pb.go编写服务端代码server.go并启动在$GOPATH/src/helloworld目录下新建文件夹server在此文件夹下新建server.go内容如下已经添加详细注释package mainimport (contextlognetgoogle.golang.org/grpcpb helloworld)const (port :50051)// 定义结构体在调用注册api的时候作为入参// 该结构体会带上SayHello方法里面是业务代码// 这样远程调用时就执行了业务代码了type server struct {// pb.go中自动生成的是个空结构体pb.UnimplementedGreeterServer}// 业务代码在此写客户端远程调用SayHello时// 会执行这里的代码func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {// 打印请求参数log.Printf(Received: %v, in.GetName())// 实例化结构体HelloReply作为返回值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)}// 实例化gRPC server结构体s : grpc.NewServer()// 服务注册pb.RegisterGreeterServer(s, server{})log.Println(开始监听等待远程调用...)if err : s.Serve(lis); err ! nil {log.Fatalf(failed to serve: %v, err)}}在server.go所在目录执行go run server.go即可启动服务控制台提示如下[golangcentos7 server]$ go run server.go 2020/12/13 08:20:32 开始监听等待远程调用...此时gRPC的服务端已经启动可以响应远程调用接下来开发客户端代码编写客户端代码client.go并启动再打开一个控制台在$GOPATH/src/helloworld目录下新建文件夹client在此文件夹下新建client.go内容如下已经添加详细注释package mainimport (contextlogostimegoogle.golang.org/grpcpb helloworld)const (address localhost:50051defaultName world)func main() {// 远程连接服务端conn, err : grpc.Dial(address, grpc.WithInsecure(), grpc.WithBlock())if err ! nil {log.Fatalf(did not connect: %v, err)}// main方法执行完毕后关闭远程连接defer conn.Close()// 实例化数据结构c : pb.NewGreeterClient(conn)// 远程调用的请求参数如果没有从命令行传入就用默认值name : defaultNameif len(os.Args) 1 {name os.Args[1]}// 超时设置ctx, cancel : context.WithTimeout(context.Background(), time.Second)defer cancel()// 远程调用r, err : c.SayHello(ctx, pb.HelloRequest{Name: name})if err ! nil {log.Fatalf(could not greet: %v, err)}// 将服务端的返回信息打印出来log.Printf(Greeting: %s, r.GetMessage())}在client.go所在目录执行go run client.go会立即向服务端发起远程调用控制台提示如下可见得到了服务端的返回信息Hello world[golangcentos7 client]$ go run client.go2020/12/13 08:38:05 Greeting: Hello world再去服务端的控制台看一下通过日志发现业务代码被执行收到了远程请求的参数[golangcentos7 server]$ go run server.go 2020/12/13 08:20:32 开始监听等待远程调用...2020/12/13 08:38:05 Received: world回到客户端控制台在命令行带参数试试输入go run client.go abc收到服务端响应如下[golangcentos7 client]$ go run client.go abc2020/12/13 08:56:36 Greeting: Hello abc再去服务端的控制台看一下成功收到了abc[golangcentos7 server]$ go run server.go 2020/12/13 08:20:32 开始监听等待远程调用...2020/12/13 08:38:05 Received: world2020/12/13 08:56:36 Received: abc至此一次常规的gRPC开发实战就完成了希望能给您一些参考接下来的文章咱们会继续深入学习gRPC欢迎关注我的公众号程序员欣宸