You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
96 lines
3.6 KiB
96 lines
3.6 KiB
|
2 weeks ago
|
// 指定使用 proto3 语法。
|
||
|
|
syntax = "proto3";
|
||
|
|
|
||
|
|
// 定义包名。在 Go 中,这会影响生成的代码所在的目录结构和包声明。
|
||
|
|
package relay;
|
||
|
|
|
||
|
|
// 指定生成的 Go 代码的包路径。
|
||
|
|
option go_package = "relay_server/proto";
|
||
|
|
|
||
|
|
// -----------------------------------------------------------------------------
|
||
|
|
// 服务定义 (Service Definition)
|
||
|
|
// -----------------------------------------------------------------------------
|
||
|
|
|
||
|
|
// InternalRelay 服务定义了服务器实例之间内部通信的 RPC 方法。
|
||
|
|
service InternalRelay {
|
||
|
|
// ProxyRequest 是一个双向流式 RPC。
|
||
|
|
// "stream" 关键字表示客户端和服务器都可以连续地发送一系列消息,
|
||
|
|
// 这对于传输大文件或实时数据流(如视频)至关重要,可以避免将整个内容加载到内存中。
|
||
|
|
rpc ProxyRequest(stream ProxyRequestMessage) returns (stream ProxyResponseMessage);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
// -----------------------------------------------------------------------------
|
||
|
|
// 请求消息定义 (Request Messages)
|
||
|
|
// -----------------------------------------------------------------------------
|
||
|
|
|
||
|
|
// ProxyRequestMessage 是从“代理实例”(接收App请求的实例)
|
||
|
|
// 发送到“目标实例”(持有设备连接的实例)的消息。
|
||
|
|
//
|
||
|
|
// 使用 `oneof` 结构可以确保每个消息要么是请求头,要么是请求体的一部分,
|
||
|
|
// 这使得在接收端处理消息时逻辑更清晰、更安全。
|
||
|
|
message ProxyRequestMessage {
|
||
|
|
oneof payload {
|
||
|
|
ProxyRequestHeader header = 1;
|
||
|
|
ProxyRequestBodyChunk body_chunk = 2;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// ProxyRequestHeader 包含了重建原始 HTTP 请求所需的所有元数据。
|
||
|
|
// 这个消息必须是客户端发送的第一个消息。
|
||
|
|
message ProxyRequestHeader {
|
||
|
|
// HTTP 方法, 例如 "GET", "POST", "PUT" 等。
|
||
|
|
string method = 1;
|
||
|
|
|
||
|
|
// 完整的请求 URL 路径,包括查询参数。
|
||
|
|
// 例如 "/tunnel/DEVICE_SN_123/api/album?page=1&size=10"
|
||
|
|
string url = 2;
|
||
|
|
|
||
|
|
// 原始的 HTTP 请求头。
|
||
|
|
// `map` 类型非常适合用来表示键值对集合。
|
||
|
|
map<string, string> headers = 3;
|
||
|
|
|
||
|
|
// 原始 App 客户端的 IP 地址和端口,用于日志记录或 X-Forwarded-For 头。
|
||
|
|
string remote_addr = 4;
|
||
|
|
|
||
|
|
// 经过认证的 App 用户的 ID,用于在目标实例上进行授权检查。
|
||
|
|
string app_user_id = 5;
|
||
|
|
}
|
||
|
|
|
||
|
|
// ProxyRequestBodyChunk 包含了一小块 HTTP 请求体的数据。
|
||
|
|
// 通过将请求体分割成多个 chunk 进行流式传输,
|
||
|
|
// 我们可以处理任意大小的上传文件,而不会耗尽服务器内存。
|
||
|
|
message ProxyRequestBodyChunk {
|
||
|
|
bytes data = 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
// -----------------------------------------------------------------------------
|
||
|
|
// 响应消息定义 (Response Messages)
|
||
|
|
// -----------------------------------------------------------------------------
|
||
|
|
|
||
|
|
// ProxyResponseMessage 是从“目标实例”发送回“代理实例”的消息。
|
||
|
|
// 同样使用 `oneof` 来区分响应头和响应体。
|
||
|
|
message ProxyResponseMessage {
|
||
|
|
oneof payload {
|
||
|
|
ProxyResponseHeader header = 1;
|
||
|
|
ProxyResponseBodyChunk body_chunk = 2;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// ProxyResponseHeader 包含了 HTTP 响应的元数据。
|
||
|
|
// 这个消息必须是服务器端在流中发送的第一个消息。
|
||
|
|
message ProxyResponseHeader {
|
||
|
|
// HTTP 状态码, 例如 200, 404, 500。
|
||
|
|
int32 status_code = 1;
|
||
|
|
|
||
|
|
// HTTP 响应头。
|
||
|
|
map<string, string> headers = 2;
|
||
|
|
}
|
||
|
|
|
||
|
|
// ProxyResponseBodyChunk 包含了一小块 HTTP 响应体的数据。
|
||
|
|
// 这使得视频播放、大文件下载等场景可以实现流式传输,
|
||
|
|
// App 客户端可以边接收数据边处理,而无需等待整个文件下载完成。
|
||
|
|
message ProxyResponseBodyChunk {
|
||
|
|
bytes data = 1;
|
||
|
|
}
|