zoukankan      html  css  js  c++  java
  • golang中使用grpc服务

    1、安装protobuf

    grpc使用protobuf作为IDL(interface descriton language),且要求protobuf 3.0以上,这里我们直接选用当前最新版本 3.8,git下载地址

    选择操作系统对应的版本下载,这里我们直接使用已经编译好的protoc可执行文件(或者下载安装包编译安装)。

    wget https://github.com/protocolbuffers/protobuf/releases/download/v3.8.0-rc1/protoc-3.8.0-rc-1-linux-x86_64.zip
    tar -zxvf protoc-3.8.0-rc-1-linux-x86_64.zip
    mv protoc-3.8.0-rc-1-linux-x86_64 /usr/local/protoc
    ln -s /usr/local/protoc/bin/protoc /usr/local/bin/protoc
    #查看 protoc
    protoc --version
    

     

    2、安装 protoc-gen-go

    go get -u github.com/golang/protobuf/protoc-gen-go
    

     

    3、安装 grpc-go 库

    git clone https://github.com/grpc/grpc-go.git $GOPATH/src/google.golang.org/grpc
    git clone https://github.com/golang/net.git $GOPATH/src/golang.org/x/net
    git clone https://github.com/golang/text.git $GOPATH/src/golang.org/x/text
    git clone https://github.com/google/go-genproto.git $GOPATH/src/google.golang.org/genproto
    
    cd $GOPATH/src/
    go install google.golang.org/grpc
    

      

    4、编辑proto文件 

    syntax = "proto3";
     
    // user 包
    package user;
    
    // 指定 go 的包路径及包名
    // option go_package="app/services;services";
    // 指定 php 的命名空间
    // option php_namespace="App\Services";
    
    // User 服务及服务接口的定义
    service User {
        rpc UserIndex(UserIndexRequest) returns (UserIndexResponse) {}
        rpc UserView(UserViewRequest) returns (UserViewResponse) {}
        rpc UserPost(UserPostRequest) returns (UserPostResponse) {}
        rpc UserDelete(UserDeleteRequest) returns (UserDeleteResponse) {}
    }
    
    // 枚举类型
    emun EnumUserSex {
        SEX_INIT = 0; // 枚举类型必须以 0 起始
        SEX_MALE = 1;
        SEX_FEMALE = 2;
    }
    
    // 用户实体模型
    message UserEntity {
        string name = 1;
        int32 age = 2;
    }
    
    // User 服务的各个接口的请求/响应结构
    message UserIndexRequest {
        int32 page = 1;
        int32 page_size = 2;
    }
    
    message UserIndexResponse {
        int32 err = 1;
        string msg = 2;
        // 返回一个 UserEntity 对象的列表数据
        repeated UserEntity data = 3;
    }
    
    message UserViewRequest {
        int32 uid = 1;
    }
    
    message UserViewResponse {
        int32 err = 1;
        string msg = 2;
        // 返回一个 UserEntity 对象
        UserEntity data = 3;
    }
    
    message UserPostRequest {
        string name = 1;
        string password = 2;
        int32 age = 3;
    }
    
    message UserPostResponse {
        int32 err = 1;
        string msg = 2;
    }
    
    message UserDeleteRequest {
        int32 uid = 1;
    }
    
    message UserDeleteResponse {
        int32 err = 1;
        string msg = 2;
    }
    

     

    5、生成接口库

    # 加载 protoc-gen-go 插件 生成 grpc 的 go 服务端/客户端
    # 注意要安装好 protoc-gen-go 插件
    protoc -I. --go_out=plugins=grpc:./user user.proto
    

    6、server端

    package main
    
    import (
    	"context"
    	"log"
    	"net"
    	"rpc/grpc/user"
    
    	"google.golang.org/grpc"
    	"google.golang.org/grpc/reflection"
    )
    
    //UserServer  实现User服务的业务对象
    type UserServer struct {
    }
    
    //UserIndex 实现了User 服务接口的所有方法
    func (u *UserServer) UserIndex(ctx context.Context, in *user.UserIndexRequest) (*user.UserIndexResponse, error) {
    
    	log.Printf("receive user index request:page %d page_size %d", in.Page, in.PageSize)
    
    	return &user.UserIndexResponse{
    		Err: 0,
    		Msg: "success",
    		Data: []*user.UserEntity{
    			{Name: "aaaa", Age: 28},
    			{Name: "bbbb", Age: 1},
    		},
    	}, nil
    }
    
    //UserView 获取详情
    func (u *UserServer) UserView(ctx context.Context, in *user.UserViewRequest) (*user.UserViewResponse, error) {
    	log.Printf("receive user uid request:uid %d", in.Uid)
    	return &user.UserViewResponse{
    		Err: 0,
    		Msg: "success",
    		Data: &user.UserEntity{
    			Name: "aaaa", Age: 28,
    		},
    	}, nil
    
    }
    
    //UserPost 提交数据
    func (u *UserServer) UserPost(ctx context.Context, in *user.UserPostRequest) (*user.UserPostResponse, error) {
    	log.Printf("receive user uid request:name %s password:%s,age:%d", in.Name, in.Password, in.Age)
    	return &user.UserPostResponse{
    		Err: 0,
    		Msg: "success",
    	}, nil
    
    }
    
    //UserDelete 删除数据
    func (u *UserServer) UserDelete(ctx context.Context, in *user.UserDeleteRequest) (*user.UserDeleteResponse, error) {
    	log.Printf("receive user uid request:uid %d", in.Uid)
    	return &user.UserDeleteResponse{
    		Err: 0,
    		Msg: "success",
    	}, nil
    
    }
    
    func main() {
    	lis, err := net.Listen("tcp", ":1234")
    	if err != nil {
    		log.Fatal("failed to listen", err)
    	}
    
    	//创建rpc服务
    	grpcServer := grpc.NewServer()
    
    	//为User服务注册业务实现 将User服务绑定到RPC服务器上
    	user.RegisterUserServer(grpcServer, &UserServer{})
    
    	//注册反射服务, 这个服务是CLI使用的, 跟服务本身没有关系
    	reflection.Register(grpcServer)
    
    	if err := grpcServer.Serve(lis); err != nil {
    		log.Fatal("faild to server,", err)
    	}
    }
    

      

    7、客户端

    package main
    
    import (
    	"context"
    	"fmt"
    	"log"
    	"rpc/grpc/user"
    	"time"
    
    	"google.golang.org/grpc"
    )
    
    func main() {
    
    	//建立链接
    	conn, err := grpc.Dial("127.0.0.1:1234", grpc.WithInsecure())
    	if err != nil {
    		log.Fatal("did not connect", err)
    
    	}
    
    	defer conn.Close()
    
    	userClient := user.NewUserClient(conn)
    
    	//设定请求超时时间 3s
    	ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
    	defer cancel()
    	//UserIndex 请求
    	userIndexResponse, err := userClient.UserIndex(ctx, &user.UserIndexRequest{
    		Page:     1,
    		PageSize: 12,
    	})
    
    	if err != nil {
    		log.Printf("user index could not greet: %v", err)
    	}
    
    	if 0 == userIndexResponse.Err {
    		log.Printf("user index success: %s", userIndexResponse.Msg)
    		// 包含 UserEntity 的数组列表
    		userEntityList := userIndexResponse.Data
    		for _, row := range userEntityList {
    			fmt.Println(row.Name, row.Age)
    		}
    	} else {
    		log.Printf("user index error: %d", userIndexResponse.Err)
    
    	}
    
    	// UserView 请求
    	userViewResponse, err := userClient.UserView(ctx, &user.UserViewRequest{Uid: 1})
    	if err != nil {
    		log.Printf("user view could not greet: %v", err)
    	}
    
    	if 0 == userViewResponse.Err {
    		log.Printf("user view success: %s", userViewResponse.Msg)
    		userEntity := userViewResponse.Data
    		fmt.Println(userEntity.Name, userEntity.Age)
    	} else {
    		log.Printf("user view error: %d", userViewResponse.Err)
    	}
    
    	// UserPost 请求
    	userPostReponse, err := userClient.UserPost(ctx, &user.UserPostRequest{Name: "big_cat", Password: "123456", Age: 29})
    	if err != nil {
    		log.Printf("user post could not greet: %v", err)
    	}
    
    	if 0 == userPostReponse.Err {
    		log.Printf("user post success: %s", userPostReponse.Msg)
    	} else {
    		log.Printf("user post error: %d", userPostReponse.Err)
    	}
    
    	// UserDelete 请求
    	userDeleteReponse, err := userClient.UserDelete(ctx, &user.UserDeleteRequest{Uid: 1})
    	if err != nil {
    		log.Printf("user delete could not greet: %v", err)
    	}
    
    	if 0 == userDeleteReponse.Err {
    		log.Printf("user delete success: %s", userDeleteReponse.Msg)
    	} else {
    		log.Printf("user delete error: %d", userDeleteReponse.Err)
    	}
    
    }
    

      

    7、启动服务/请求服务

    go run server.go
    go run client.go
    

     

    运行结果:

    僵尸将臣
  • 相关阅读:
    软件测试工具
    Linux笔记
    Google Test
    字典dict()
    元组tuple 可迭代对象
    列表list
    一些总结
    format()
    列表list
    format() expandtabs() 输入表格数据
  • 原文地址:https://www.cnblogs.com/sunshenggang/p/12396500.html
Copyright © 2011-2022 走看看