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 }