【转】Golang-RPC(五):golang的net-rpc结合protobuf实现rpc通讯
-----------------------
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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
2020-03-12 【转】golang 并发程序写入map两种实现方式sync.Mutex和chan的效率对比
2018-03-12 php 获取TZ时间格式
2014-03-12 html 页面视图中的资源文件(css/js/image)的路径问题。