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

 

运行结果:

 

 

 

posted @ 2020-03-02 16:49  我和僵尸有个约会  阅读(3339)  评论(0编辑  收藏  举报