gRPC 在Golang中的简单使用

gRPC 是 Google 开源的一个高性能的 RPC(Remote Procedure Call) 框架,具有跨语言、跨平台的特性。

使用gRPC前 需要做的前期铺垫:

1、安装接口设计语言 Protocol buffer 的编译器 protoc,下载对应版本的protobuf  https://github.com/protocolbuffers/protobuf/releases ,并将其放在GOPATH\bin下

2、安装golang插件 

go install google.golang.org/protobuf/cmd/protoc-gen-go
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc

 下载完所有依赖以后,可以正式编写proto文件了

1、

 ①新建一个.proto文件

// 指定使用 proto3 版本
syntax = "proto3";
option go_package = "./;login_proto";
// 随便定义一个包名
package grpc.service.login;

// 定义一个服务名
service Login {
// 定义服务内的方法
rpc Login (LoginRequest) returns (LoginReply) {}
}

// 客户端请求的参数
message LoginRequest {
string account = 1;
string password = 2;
}

// 服务端返回的参数
message LoginReply {
int32 code = 1;
string key = 2;
string message = 3;
string access_token = 4;
string user_id = 5;
string user_code = 6;
string user_name = 7;
string group_name = 8;
string duty_name = 9;
string position_name = 10;
}

  ②使用protoc编译刚才编写的.proto文件

③编译完成后,目录下会有以下三个文件

④proto具有跨语言性,如果你想编译其他语言的文件,修改编译命令即可,比如编译java可调用的grpc,可以使用

2、编写服务端及客户端方法

服务端(业务数据做了脱敏)

编写服务端时,需要将编译好的两个.go文件放到服务端项目目录中。

我利用rpc服务端做了一个http转发,主要是前两个方法

package main

import (
	"bytes"
	"context"
	"encoding/json"
	"github.com/skywalkerOAO/Gotos"
	"google.golang.org/grpc"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	proto "rpctest/proto"
)

const (
	// 绑定的端口
	port = ":10000"
)

type server struct {
	proto.UnimplementedLoginServer
}

func (s *server) Login(ctx context.Context, in *proto.LoginRequest) (*proto.LoginReply, error) {
	resp := LoginSim(in.GetAccount(), in.GetPassword())
	reply := &proto.LoginReply{
		Message: resp,
	}
	return reply, nil
}

func main() {
	lis, err := net.Listen("tcp", port)
	if err != nil {
		log.Fatalf("failed to listen: %v", err)
	}

	srv := grpc.NewServer()
	// 注册服务
	proto.RegisterLoginServer(srv, &server{})

	log.Println("gRPC server is running...")
	// 起服务
	if err := srv.Serve(lis); err != nil {
		log.Fatalf("failed to serve: %v", err)
	}
}

func LoginSim(Account string, Password string) string {
	type QBody struct {
		Account  string `json:"account"`
		Password string `json:"password"`
	}

	List := QBody{Account, Password}
	ReqBody, _ := json.Marshal(List)
	IOReader := bytes.NewReader(ReqBody)
	client := &http.Client{}
	resp, _ := http.NewRequest(
		"POST",
		"http://xxxx",
		IOReader)
	resp.Header.Set("platform_code", "f7dacf4fdbca77f4dd3a252a46f9d73c")
	resp.Header.Set("Content-Type", "application/json")
	req, err := client.Do(resp)
	if err != nil {
		return Gotos.Message("远程服务器没有反应", 500)
	}
	body, _ := ioutil.ReadAll(req.Body)
	return string(body)
}

 客户端

使用客户端时,需要把我们编译好的两个文件复制到你的客户端项目目录中。

package brpc

import (
	login_proto "bhd/proto"
	"context"
	"github.com/skywalkerOAO/Gotos"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"
	"log"
	"time"
)

const (
	address = "10.4.52.74:10000"
)

func Login(Account string, Password string) (string, error) {
	// Set up a connection to the server.
	conn, err := grpc.Dial(address, grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithBlock(), grpc.WithTimeout(3000*time.Millisecond))
	if err != nil {
		return Gotos.Message("服务器内部错误", 500), err
	}
	defer conn.Close()
	c := login_proto.NewLoginClient(conn)
	acc := Account
	psw := Password
	ctx, cancel := context.WithTimeout(context.Background(), 30000*time.Millisecond)
	defer cancel()
	r, err := c.Login(ctx, &login_proto.LoginRequest{Account: acc, Password: psw})
	if err != nil {
		log.Fatalf("POST FAIL: %v", err)
	}
	return r.GetMessage(), nil
}

3、启动服务端,使用客户端调用一下

posted @ 2022-09-17 11:01  skywa1ker  阅读(523)  评论(0编辑  收藏  举报