好好爱自己!

【转】Golang-RPC(五):golang的net-rpc结合protobuf实现rpc通讯

 

转,原文:https://blog.csdn.net/raoxiaoya/article/details/109533275?share_token=27c49b7e-648a-4e26-920b-fad5f4874535

-----------------------

 

net/rpc 包实现了基于 tcp/http 协议的 gob 编码的rpc客户端与服务端。
net/rpc/jsonrpc 包实现了基于 tcp 协议 json 编码的rpc客户端与服务端。

要想实现基于 tcp 协议 protobuf 编码的rpc客户端与服务端,可以在 net/rpc 的基础上实现一对 serverCodec 和 clientCodec 。

需要安装 protoc 和 protoc-gen-go,可参考 https://blog.csdn.net/raoxiaoya/article/details/109496431

下载依赖

go get -u github.com/mars9/codec
1
编写 message.proto 文件:

syntax = "proto3";

option go_package = "./pbs;message";

package message;

//订单请求参数
message OrderRequest {
string orderId = 1;
}

//订单信息
message OrderInfo {
string Id = 1;
float Price = 2;
int64 Status = 3;
}

此文件定义了请求参数的结构和响应参数的结构。

生成 pb 文件:

protoc ./message.proto --go_out=./
1
得到文件 pbs/message.pb.go

编写服务 repo/order.go:

/*
-- @Time : 2020/11/3 14:41
-- @Author : raoxiaoya
-- @Desc :
*/
package repo

import (
"errors"

message "demo1/go-protobuf/pbs"
)

type Order struct {}

type OrderInfo struct {
Id string
Price float64
Status int
}

func (o *Order) GetOne(orderRequest *message.OrderRequest, orderInfo *message.OrderInfo) error {
if orderRequest.OrderId == "" {
return errors.New("orderId is invalid")
}

*orderInfo = message.OrderInfo{
Id: orderRequest.OrderId,
Price: 100.00,
Status: 1,
}

return nil
}


此服务提供一个方法 GetOne ,通过订单编号查询订单信息。

服务端程序 service.go:

package main

import (
"net"
"net/rpc"

"demo1/go-protobuf/repo"
"github.com/mars9/codec"
)

func main() {
rpc.Register(new(repo.Order))

listen, err := net.Listen("tcp", ":8100")
if err != nil {
panic(err.Error())
}

for {
conn, err := listen.Accept()
if err != nil {
continue
}
go rpc.ServeCodec(codec.NewServerCodec(conn))
}
}


客户端程序 client.go:

package main

import (
"fmt"
"net"
"net/rpc"

"demo1/go-protobuf/pbs"
"github.com/mars9/codec"
)

func main() {
Client()
}

func Client() {
conn, err := net.Dial("tcp", "localhost:8100")
if err != nil {
panic(err)
}
client := rpc.NewClientWithCodec(codec.NewClientCodec(conn))

request := message.OrderRequest{OrderId: "201907310001"}
var response message.OrderInfo
err = client.Call("Order.GetOne", &request, &response)
if err != nil {
panic(err)
}

fmt.Println(response)
}

go run service.go

go run client.go

客户端输出:

{{{} [] [] 0xc0001a48b8} 0 [] 201907310001 100 1}
1
说明通讯已成功建立。

其他编码格式:
JSON-RPC 2.0
bsonrpc:
messagepack
protobuf

关于Go序列化库的性能的比较你可以参考 gosercomp
————————————————
版权声明:本文为CSDN博主「raoxiaoya」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/raoxiaoya/article/details/109533275

posted @ 2023-03-12 23:58  立志做一个好的程序员  阅读(113)  评论(0编辑  收藏  举报

不断学习创作,与自己快乐相处