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

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

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

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

下载依赖

go get -u github.com/mars9/codec

编写 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=./

得到文件 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}

说明通讯已成功建立。

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

关于Go序列化库的性能的比较你可以参考 gosercomp

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值