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、启动服务端,使用客户端调用一下