zoukankan      html  css  js  c++  java
  • Go-gRPC的简单使用

    RPC简介

    Remote Procedure Call,缩写为 RPC)是一个计算机通信协议。RPC是一种服务器-客户端(Client/Server)模式,经典实现是一个通过发送请求-接受回应进行信息交互的系统

    gRPC开发步骤

    • 编写.proto文件,生成指定语言源代码
    • 编写服务端代码
    • 编写客户端代码

    安装

    创建项目

    mkdir grpc_demo
    cd grpc_demo
    go mod init grpc_demo
    

    安装gRPC

    go get -u google.golang.org/grpc
    

    安装Protocol Buffers v3

    安装用于生成gRPC服务代码的协议编译器。软件地址

    • 解压下载好的文件
    • protoc二进制文件的路径加到环境变量中
    • 安装protoc的Go插件go get -u github.com/golang/protobuf/protoc-gen-go
      • 编译插件protoc-gen-go将会安装到$GOBIN,默认是$GOPATH/bin,它必须在你的$PATH中以便协议编译器protoc能够找到它。
    C:UsersAlbin>d:
    
    D:>cd D:PracticeScriptsgosrcgitee.comliubstdgo
    
    D:PracticeScriptsgosrcgitee.comliubstdgo>mkdir grpc_demo
    
    D:PracticeScriptsgosrcgitee.comliubstdgo>cd grpc_demo
    
    D:PracticeScriptsgosrcgitee.comliubstdgogrpc_demo>go mod init grpc_demo
    go: creating new go.mod: module grpc_demo
    
    D:PracticeScriptsgosrcgitee.comliubstdgogrpc_demo>go get -u google.golang.org/grpc
    go: downloading golang.org/x/net v0.0.0-20190311183353-d8887717615a
    go: extracting golang.org/x/net v0.0.0-20190311183353-d8887717615a
    go: downloading golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a
    go: extracting golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a
    go: finding golang.org/x/sys latest
    go: finding google.golang.org/genproto latest
    go: finding golang.org/x/net latest
    
    D:PracticeScriptsgosrcgitee.comliubstdgogrpc_demo>go get -u github.com/golang/protobuf/protoc-gen-go
    

    示例

    创建项目代码目录结构

    mkdir helloworldpb
    mkdir helloworldserver
    mkdir helloworldclient
    
    D:PracticeScriptsgosrcgitee.comliubstdgogrpc_demo>tree
    文件夹 PATH 列表
    卷序列号为 A021-AE06
    D:.
    └─helloworld
        ├─client
        ├─pb
        └─server
    

    编写proto代码

    gRPC是基于Protocol Buffers。

    Protocol Buffers是一种与语言无关,平台无关的可扩展机制,用于序列化结构化数据。使用Protocol Buffers可以一次定义结构化的数据,然后可以使用特殊生成的源代码轻松地在各种数据流中使用各种语言编写和读取结构化数据。

    编写文件

    vi helloworld/pb/helloworld.proto

    syntax = "proto3"; // 版本声明,使用Protocol Buffers v3版本
    
    package pb; // 包名
    
    
    // 定义一个打招呼服务
    service Greeter {
        // SayHello 方法
        rpc SayHello (HelloRequest) returns (HelloReply) {}
    }
    
    // 包含人名的一个请求消息
    message HelloRequest {
        string name = 1;
    }
    
    // 包含问候语的响应消息
    message HelloReply {
        string message = 1;
    }
    
    生成go语言源代码
    protoc -I helloworld/ helloworld/pb/helloworld.proto --go_out=plugins=grpc:helloworld
    

    gRPC_demo/helloworld/pb目录下会生成helloworld.pb.go文件。

    编写server端go代码

    vi grpc_demo/helloworld/server/server.go

    package main
    
    import (
    	"fmt"
    	"net"
    
    	pb "grpc_demo/helloworld/pb"
    
    	"golang.org/x/net/context"
    	"google.golang.org/grpc"
    	"google.golang.org/grpc/reflection"
    )
    
    type server struct{}
    
    func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
    	return &pb.HelloReply{Message: "hello " + in.Name}, nil
    }
    
    func main() {
    	// 监听本地的8972端口
    	lsnr, err := net.Listen("tcp", ":8972")
    	if err != nil {
    		fmt.Printf("failed to listen: %v", err)
    		return
    	}
    
    	s := grpc.NewServer()                  // 创建gRPC服务器
    	pb.RegisterGreeterServer(s, &server{}) // 在gRPC服务端注册服务
    
    	reflection.Register(s) // 在给定的gRPC服务器上注册服务器反射服务
    
    	// Serve方法在lsnr上接受传入连接,为每个连接创建一个ServerTransport和server的goroutine。
    	// 该goroutine读取gRPC请求,然后调用已注册的处理程序来响应它们。
    	err = s.Serve(lsnr)
    	if err != nil {
    		fmt.Printf("failed to serve: %v", err)
    		return
    	}
    }
    
    
    编译并执行
    cd helloworld/server
    go build
    ./server
    

    编写客户端go代码

    package main
    
    import (
    	"context"
    	"fmt"
    
    	pb "grpc_demo/helloworld/pb"
    
    	"google.golang.org/grpc"
    )
    
    func main() {
    	// 连接服务器
    	conn, err := grpc.Dial(":8972", grpc.WithInsecure())
    	if err != nil {
    		fmt.Printf("faild to connect: %v", err)
    
    	}
    	defer conn.Close()
    
    	c := pb.NewGreeterClient(conn)
    
    	// 调用服务端的SayHello
    
    	r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: "biao"})
    
    	if err != nil {
    		fmt.Printf("could not greet: %v", err)
    	}
    	fmt.Printf("Greeting: %s !
    ", r.Message)
    }
    
    

    运行

    image-20200817152151917

    gRPC跨语言调用

    使用Python语言编写Client,然后向上面使用go语言编写的server发送RPC请求

    安装相关python模块
    pip3 install grpcio
    pip3 install grpcio-tools
    pip3 install protobuf
    

    image-20200817153035358

    生成python代码

    gRPC_demo目录执行命令

    python -m grpc_tools.protoc -I helloworld/pb/ --python_out=helloworld/client/ --grpc_python_out=helloworld/client/ helloworld/pb/helloworld.proto
    
    

    上面命令执行完成后,在grpc_demo/helloworld/client/目录生成如下两个python文件

    image-20200817154205980

    编写python版client代码
    #!/usr/bin/env python
    # coding=utf-8
    
    import logging
    import grpc
    
    import helloworld_pb2
    import helloworld_pb2_grpc
    
    def run():
        # 注意(gRPC Python Team): .close()方法在channel上是可用的。
        # 并且应该在with语句不符合代码需求的情况下使用。
        with grpc.insecure_channel('localhost:8972') as channel:
            stub = helloworld_pb2_grpc.GreeterStub(channel)
            response = stub.SayHello(helloworld_pb2.HelloRequest(name='标'))
        print("Greeter client received: {}!".format(response.message))
    
    
    if __name__ == '__main__':
        logging.basicConfig()
        run()
    
    运行

    image-20200817154821958

  • 相关阅读:
    vsftpd原理与搭建
    vsftpd的日志格式
    ftp内置命令
    tcp_tw_reuse、tcp_tw_recycle和tcp_timestamps
    http_code 499、500、502、503、504
    mtr命令网络诊断
    tracert——Windows路由追踪
    linux GPT分区及扩容
    Linux磁盘扩容
    linux磁盘分区、挂载
  • 原文地址:https://www.cnblogs.com/binliubiao/p/13518149.html
Copyright © 2011-2022 走看看