当前位置: 首页 > article >正文

rpc和proto

rpc全称远程过程控制,说白了是一种对信息发送和接收的规则编写方法,来自google,这些规则会以protobuf代码存到proto文件里。我以autoGen中agent_worker.proto为例,大概长这样

syntax = "proto3";

package agents;

option csharp_namespace = "Microsoft.AutoGen.Protobuf";

import "cloudevent.proto";
import "google/protobuf/any.proto";


message AgentId {
    string type = 1;
    string key = 2;
}

message Payload {
    string data_type = 1;
    string data_content_type = 2;
    bytes data = 3;
}

message RpcRequest {
    string request_id = 1;
    optional AgentId source = 2;
    AgentId target = 3;
    string method = 4;
    Payload payload = 5;
    map<string, string> metadata = 6;
}

message RpcResponse {
    string request_id = 1;
    Payload payload = 2;
    string error = 3;
    map<string, string> metadata = 4;
}

message RegisterAgentTypeRequest {
    string type = 1;
}

message RegisterAgentTypeResponse {
}

message TypeSubscription {
    string topic_type = 1;
    string agent_type = 2;
}

message TypePrefixSubscription {
    string topic_type_prefix = 1;
    string agent_type = 2;
}

message Subscription {
    string id = 1;
    oneof subscription {
        TypeSubscription typeSubscription = 2;
        TypePrefixSubscription typePrefixSubscription = 3;
    }
}

message AddSubscriptionRequest {
    Subscription subscription = 1;
}

message AddSubscriptionResponse {
}

message RemoveSubscriptionRequest {
    string id = 1;
}

message RemoveSubscriptionResponse {
}

message GetSubscriptionsRequest {}
message GetSubscriptionsResponse {
    repeated Subscription subscriptions = 1;
}

message Message {
    oneof message {
        RpcRequest request = 1;
        RpcResponse response = 2;
        io.cloudevents.v1.CloudEvent cloudEvent = 3;
    }
}

message SaveStateRequest {
    AgentId agentId = 1;
}

message SaveStateResponse {
    string state = 1;
    optional string error = 2;
}

message LoadStateRequest {
    AgentId agentId = 1;
    string state = 2;
}
message LoadStateResponse {
    optional string error = 1;
}

message ControlMessage {
    // A response message should have the same id as the request message
    string rpc_id = 1;
    // This is either:
    // agentid=AGENT_ID
    // clientid=CLIENT_ID
    string destination = 2;
    // This is either:
    // agentid=AGENT_ID
    // clientid=CLIENT_ID
    // Empty string means the message is a response
    optional string respond_to = 3;
    // One of:
    //     SaveStateRequest saveStateRequest = 2;
    //     SaveStateResponse saveStateResponse = 3;
    //     LoadStateRequest loadStateRequest = 4;
    //     LoadStateResponse loadStateResponse = 5;
    google.protobuf.Any rpcMessage = 4;
}

service AgentRpc {
    rpc OpenChannel (stream Message) returns (stream Message);
    rpc OpenControlChannel (stream ControlMessage) returns (stream ControlMessage);
    rpc RegisterAgent(RegisterAgentTypeRequest) returns (RegisterAgentTypeResponse);
    rpc AddSubscription(AddSubscriptionRequest) returns (AddSubscriptionResponse);
    rpc RemoveSubscription(RemoveSubscriptionRequest) returns (RemoveSubscriptionResponse);
    rpc GetSubscriptions(GetSubscriptionsRequest) returns (GetSubscriptionsResponse);
}

为什么要用protobuf定义rpc呢?首先,rpc是一种比http和restapi更轻量的协议,应该都知道http要有http头,header,rpc采用更紧凑的编码方式,具体我也不懂,反正它的协议叫做gRPC。然后,为了让rpc流行起来,需要一个在各种语言中都能被使用的方法,protobuf作为一种中间语言,在编写后可以被编译成各种语言的版本,然后供各语言的代码调用,这个编译器叫protoc,c是complier。

你可以简单地把proto代码看作是对数据结构的定义,就像python的dataclass一样。有几个字段需要解释:
oneof:它里面会包含多个变量名,在你实例化对应数据类时,只能出现其中一个变量,其他的不可用。
map:看作dict。
repeat:看作list。
packed:是跟在某些数据类型的变量后面的定义,用于注明这些值是否需要精简地序列化,proto3里默认开启。
enum Status:定义一个枚举数据类型Status。像python一样,Status会定义一个名字并附上具体的值,之后可以用Status定义其他变量的类型。
message:定义发送的信息的数据结构。
数据类型:在变量名前面注明,可以是某个定义完的数据结构,和python一样。
变量 = 数字:数字是编号,用于数据在序列化和反序列化时作标记和识别。因此,它可以不是顺序的,可以随便定义(但是最好别这样做)。
service:与message平级,用于定义一个服务所提供的所有rpc服务。
rpc:注明这是一个rpc服务,将注明发送和接收的message样式。
stream:注明这是一个流式传输。如果不是流式传输,rpc服务只会做到“客户端发送message,服务端返回对应的message”,就像一个request一样。
nest message:它只是一种嵌套形式,在message里定义一个message,毕竟message也是一个变量类型。
reserved:可以用来预留编号和变量名。
DynamicMessage:它用来支持动态解析,在不知道来犯的message类型时,对方可能同时传过来一个proto文件的descriptor文件,用它来动态解析message。

protobuf已经到protobuf3了,之前所有参数都可以注明可选or必选,现在都是可选。


http://www.kler.cn/a/579395.html

相关文章:

  • 【YOLOv12改进trick】多尺度大核注意力机制MLKA模块引入YOLOv12,实现多尺度目标检测涨点,含创新点Python代码,方便发论文
  • 手写Tomcat:实现基本功能
  • CTFHub-FastCGI协议/Redis协议
  • 行式数据库与列式数据库区别
  • 【渗透测试】基于时间的盲注(Time-Based Blind SQL Injection)
  • elasticsearch是哪家的
  • 物联网中如何解决网络复杂性的问题
  • 爬虫去重:数据采集时如何进行去重,及去重优化策略
  • 2025最新Postman、Apipost和Apifox API 协议与工具选择方案解析
  • PG vs MySQL 主从复制的异同点
  • hom_mat2d_to_affine_par 的c#实现
  • hadoop集群HDFS读写性能测试
  • 使用mergekit合并大型语言模型
  • 使用chroot预安装软件到ubuntu22中
  • 【学习笔记】【DeepSeek AI 医生】2-2 AI家庭医生课程内容介绍
  • vscode的终端无法运行vue或者node等命令解决方案
  • 在uni-app中使用SQLite实现离线下数据同步:从封装到实践
  • 框架基本知识总结 Day15
  • 字母异位词分组 力扣49
  • UI自动化测试Selenium安装教程(1)