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.

120 lines
3.0 KiB
Go

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.

package request
import (
"encoding/json"
"fmt"
protocolpkg "github.com/noahlann/nnet/pkg/protocol"
requestpkg "github.com/noahlann/nnet/pkg/request"
)
// requestImpl 请求实现
// 实现了Request和RequestSetter接口
type requestImpl struct {
raw []byte
data interface{}
dataBytes []byte
header requestpkg.FrameHeader
protocol protocolpkg.Protocol
}
// 确保requestImpl实现了RequestSetter接口
var _ RequestSetter = (*requestImpl)(nil)
// New 创建新的请求对象
func New(raw []byte, protocol protocolpkg.Protocol) requestpkg.Request {
return &requestImpl{
raw: raw,
protocol: protocol,
}
}
// Raw 获取原始数据
func (r *requestImpl) Raw() []byte {
return r.raw
}
// Data 获取数据部分已自动解码为Go对象
func (r *requestImpl) Data() interface{} {
return r.data
}
// SetData 设置数据部分(内部使用,导出以供服务器使用)
func (r *requestImpl) SetData(data interface{}) {
r.data = data
}
// Bind 绑定到指定的结构体
func (r *requestImpl) Bind(v interface{}) error {
// 如果Data已经存在直接使用Data
if r.data != nil {
// 使用反射将data的值复制到v
// 这里简化处理实际可以使用json或其他序列化方式
return bindDataToStruct(r.data, v)
}
// 如果Data不存在但有DataBytes使用DataBytes进行解码
if len(r.dataBytes) > 0 {
// 这里需要知道使用什么codec但Request没有codec信息
// 所以Bind方法主要用于将已解码的Data绑定到指定的struct
// 如果需要从DataBytes解码应该直接使用Data()获取结果
return fmt.Errorf("data bytes available but no codec specified, use Data() method instead")
}
return fmt.Errorf("no data available to bind")
}
// bindDataToStruct 将data绑定到struct
func bindDataToStruct(data interface{}, v interface{}) error {
// 使用JSON作为中间格式进行绑定
// 这适用于大部分场景
dataBytes, err := json.Marshal(data)
if err != nil {
return fmt.Errorf("failed to marshal data: %w", err)
}
return json.Unmarshal(dataBytes, v)
}
// Header 获取协议帧头
func (r *requestImpl) Header() requestpkg.FrameHeader {
return r.header
}
// SetHeader 设置协议帧头(内部使用,导出以供服务器使用)
func (r *requestImpl) SetHeader(header requestpkg.FrameHeader) {
r.header = header
}
// DataBytes 获取数据部分的原始字节
func (r *requestImpl) DataBytes() []byte {
return r.dataBytes
}
// SetDataBytes 设置数据部分的原始字节(内部使用,导出以供服务器使用)
func (r *requestImpl) SetDataBytes(dataBytes []byte) {
r.dataBytes = dataBytes
}
// Protocol 获取协议信息
func (r *requestImpl) Protocol() protocolpkg.Protocol {
return r.protocol
}
// ProtocolVersion 获取协议版本
func (r *requestImpl) ProtocolVersion() string {
if r.protocol != nil {
return r.protocol.Version()
}
return ""
}
// Reset 重置Request状态用于对象池
func (r *requestImpl) Reset() {
r.raw = nil
r.data = nil
r.dataBytes = nil
r.header = nil
r.protocol = nil
}