You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

264 lines
5.8 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# API设计文档
## 核心接口设计
### 1. Context上下文
```go
type Context interface {
context.Context
// 获取Request和Response对象
Request() request.Request
Response() response.Response
Connection() Connection
// 状态管理
Set(key string, value interface{})
Get(key string) interface{}
MustGet(key string) interface{}
}
```
### 2. Request请求
```go
type Request interface {
// Raw 获取原始数据(未解码的字节)
Raw() []byte
// Data 获取协议解码后的数据(去除帧头后的字节)
Data() []byte
// Decode 解码为Go对象经过protocol decode + codec decode
Decode(v interface{}) error
// DecodeWithCodec 使用指定的编解码器解码
DecodeWithCodec(v interface{}, codecName string) error
// Header 获取协议帧头(如果有)
Header() FrameHeader
// Protocol 获取协议信息
Protocol() protocol.Protocol
// ProtocolVersion 获取协议版本
ProtocolVersion() string
}
```
### 3. Response响应
```go
type Response interface {
// Write 写入数据(自动编码)
Write(data interface{}) error
// WriteWithCodec 使用指定的编解码器写入数据
WriteWithCodec(data interface{}, codecName string) error
// WriteBytes 写入原始字节(绕过编码)
WriteBytes(data []byte) error
// WriteString 写入字符串
WriteString(s string) error
// SetHeader 设置协议帧头(如果有)
SetHeader(header FrameHeader) error
// Header 获取协议帧头
Header() FrameHeader
// Send 发送响应(如果使用缓冲模式)
Send() error
// Protocol 获取协议信息
Protocol() protocol.Protocol
}
```
### 4. Protocol协议
```go
type Protocol interface {
// Name 获取协议名称
Name() string
// Version 获取协议版本
Version() string
// HasHeader 是否有帧头无帧头协议返回false
HasHeader() bool
// Encode 编码消息(添加帧头)
Encode(data []byte, header FrameHeader) ([]byte, error)
// Decode 解码消息(提取帧头和数据)
Decode(data []byte) (FrameHeader, []byte, error)
// Handle 处理消息(可选)
Handle(ctx context.Context, data []byte) ([]byte, error)
}
```
### 5. FrameHeader协议帧头
```go
type FrameHeader interface {
// Get 获取帧头字段
Get(key string) interface{}
// Set 设置帧头字段
Set(key string, value interface{})
// Encode 编码为字节
Encode() ([]byte, error)
// Decode 从字节解码
Decode(data []byte) error
}
```
## 使用示例
### 基本使用(有帧头协议)
```go
func handler(ctx context.Context) error {
req := ctx.Request()
resp := ctx.Response()
// 读取协议帧头
header := req.Header()
if header != nil {
messageType := header.Get("message_type")
// 使用帧头信息
}
// 读取数据(自动解码)
var requestData MyRequest
if err := req.Decode(&requestData); err != nil {
return err
}
// 处理业务逻辑
responseData := MyResponse{
Code: 200,
Data: "success",
}
// 设置响应帧头
respHeader := resp.Header()
if respHeader != nil {
respHeader.Set("message_type", 0x01)
}
// 写入响应(自动编码)
return resp.Write(responseData)
}
```
### 无帧头协议
```go
func handler(ctx context.Context) error {
req := ctx.Request()
resp := ctx.Response()
// 无帧头协议,直接读取原始数据
rawData := req.Data() // 或 req.Raw()
// 处理数据
result := processData(rawData)
// 写入响应(协议会自动添加\n等分隔符
return resp.WriteString(result)
}
```
### 指定编解码器
```go
func handler(ctx context.Context) error {
req := ctx.Request()
resp := ctx.Response()
// 使用指定的编解码器解码
var data MyData
if err := req.DecodeWithCodec(&data, "msgpack"); err != nil {
return err
}
// 使用指定的编解码器编码
return resp.WriteWithCodec(MyResponse{Code: 200}, "msgpack")
}
```
### 自定义协议帧头
```go
func handler(ctx context.Context) error {
req := ctx.Request()
resp := ctx.Response()
// 读取请求帧头
reqHeader := req.Header()
if reqHeader != nil {
// 获取帧头字段
msgType := reqHeader.Get("message_type")
seqNum := reqHeader.Get("sequence")
// ...
}
// 读取数据
var data MyData
req.Decode(&data)
// 创建响应帧头
respHeader := resp.Header()
if respHeader != nil {
respHeader.Set("message_type", 0x02)
respHeader.Set("sequence", seqNum)
respHeader.Set("status", 0)
}
// 写入响应
return resp.Write(MyResponse{Code: 200})
}
```
## 数据流程
### 读数据流程
```
1. Connection.Read() → []byte (原始字节)
2. Protocol.Decode() → FrameHeader + []byte (帧头 + 数据)
3. Request.Data() → []byte (数据部分)
4. Request.Decode() → interface{} (Go对象经过codec decode)
```
### 写数据流程
```
1. Response.Write(interface{}) → Go对象
2. Codec.Encode() → []byte (序列化后的数据)
3. Protocol.Encode() → []byte (添加帧头)
4. Connection.Write() → 发送到客户端
```
## 优势
1. **清晰的职责分离**Context只负责状态管理Request负责读取Response负责写入
2. **灵活的协议支持**:支持有帧头和无帧头协议
3. **现代化的API**:简洁、直观、类型安全
4. **易于扩展**:可以轻松添加新的协议和编解码器
5. **类型安全**使用接口和泛型Go 1.18+)保证类型安全