新中转服务
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

// 指定使用 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;
}