9.3 自定义代理协议

UDPack Client 与 UDPack Server 之间通过 UDPack 协议通信并相互转发流量。在 UDPack 协议之上,还需要自定义一个简单的代理协议。该代理协议同样是二进制协议,并基于 protobuf 定义。

自定义代理协议

// proto/packet.proto
syntax = "proto3";

message Packet
{

  string sid = 1;
  string cmd = 2;
  Authority authority = 3;
  ConnectRes connectRes = 4;
  bytes buf = 5;
  string reason = 6;
}

message Authority {

    string domain = 1;
    string ip = 2;
    uint32 port = 3;
}

message ConnectRes {

    bool succeeded = 1;
    string local_address = 2;
    uint32 local_port = 3;
}
  • sid: 唯一标识 Browser 与 UDPack Client 之间的一个 TCP 连接
  • cmd: 命令字
    • connect: 表示 UDPack Client 请求 UDPack Server 打开一个到某个服务器的连接通道,或者 UDPack Server 打开通道后的响应
      • authority: UDPack Client 请求打开连接的网站域
        • domain: 域名
        • ip: ip 地址
        • port: 端口
      • connectRes: UDPack Server 打开通道后的响应
        • succeeded: 是否成功
        • local_address: UDPack Server 打开连接通道时的 ip 地址
        • local_port: UDPack Server 打开连接通道时的端口
    • data: UDPack Client 与 UDPack Server 之间互相转发数据
      • buf: 转发字节数组
    • terminate: 通知另一端,转发数据已结束
      • reason: 结束原因

生成编解码代码

  • 安装 protobufjs
$ npm i protobufjs --save
  • 代码生成
$ node_modules/protobufjs/bin/pbjs -t static-module proto/packet.proto -o proto/packet.js

项目中引入 proto/packet.js 模块,可以把上方定义 Packet 对象序列化为字节数组,也可以把字节数组反序列化为 Packet 对象。UDPack 协议可以发送任意长度的字节数组,因此和 protobuf 结合使用是很方便的,通过 proto/packet.js 序列化 Packet 为字节数组然后把数据发送出去。收到的字节数组可以通过 proto/packet.js 反序列化为 Packet 对象,并进行相关处理逻辑。