"feat(socket): 添加跨域请求处理并集成enum依赖,优化TCP连接数据注入"
This commit is contained in:
236
common/serialize/ser.go
Normal file
236
common/serialize/ser.go
Normal file
@@ -0,0 +1,236 @@
|
||||
package serialize
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gctx"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"github.com/gogf/gf/v2/util/gvalid"
|
||||
"github.com/tnnmigga/enum"
|
||||
)
|
||||
|
||||
var lengthtype = enum.New[struct {
|
||||
LENGTH_FIRST int
|
||||
FIXED_LENGTH int
|
||||
}]()
|
||||
|
||||
// PacketSerializer 定义序列化函数类型,将数据转换为字节切片
|
||||
type PacketSerializer[T any] func(data T) ([]byte, error)
|
||||
|
||||
// PacketDeserializer 定义反序列化函数类型,将字节切片转换为数据
|
||||
type PacketDeserializer[T any] func(data []byte) (T, error)
|
||||
|
||||
// PacketHandler 封装序列化和反序列化处理函数
|
||||
type PacketHandler[T any] struct {
|
||||
Serialize PacketSerializer[T] // 序列化函数
|
||||
Deserialize PacketDeserializer[T] // 反序列化函数
|
||||
}
|
||||
|
||||
|
||||
|
||||
func serializebase[T any](field reflect.StructField, buf *bytes.Buffer, writedata any) error {
|
||||
|
||||
|
||||
if field.Type.Kind() == reflect.Slice { //|| field.Type.Kind() == reflect.Array}
|
||||
|
||||
datatype := make(chan int, 1)
|
||||
FIXED_LENGTH := func(ctx context.Context, in gvalid.RuleFuncInput) error {
|
||||
if in.Field == field.Name { //判断相同
|
||||
datatype <- lengthtype.FIXED_LENGTH
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
LENGTH_FIRST := func(ctx context.Context, in gvalid.RuleFuncInput) error {
|
||||
datatype <- lengthtype.FIXED_LENGTH
|
||||
// fmt.Println(in)
|
||||
return nil
|
||||
}
|
||||
length := func(ctx context.Context, in gvalid.RuleFuncInput) error {
|
||||
tem := <-datatype
|
||||
close(datatype)
|
||||
writelen := 0
|
||||
if parts := strings.Split(in.Rule, ":"); len(parts) > 1 {
|
||||
writelen = gconv.Int(strings.TrimSpace(parts[1]))
|
||||
|
||||
}
|
||||
switch tem {
|
||||
case lengthtype.FIXED_LENGTH: //in.value
|
||||
tempslice := gconv.SliceAny(writedata)
|
||||
temp := make([]byte, writelen-len(tempslice))
|
||||
|
||||
for i := 0; i < len(tempslice); i++ {
|
||||
tempdata := tempslice[i]
|
||||
fmt.Println(i)
|
||||
serializebase[T]( field, buf, tempdata) //todo递归序列化
|
||||
// copy(temp, date1)
|
||||
// if err := binary.Write(buf, binary.BigEndian, temp); err != nil {
|
||||
// return nil
|
||||
// }
|
||||
}
|
||||
|
||||
if err := binary.Write(buf, binary.BigEndian, temp); err != nil {
|
||||
return nil
|
||||
}
|
||||
case lengthtype.LENGTH_FIRST:
|
||||
// temp := make([]byte, writelen)
|
||||
// date1 := []byte(writedata.(string))
|
||||
// copy(temp, date1)
|
||||
// if err := binary.Write(buf, binary.BigEndian, temp); err != nil {
|
||||
// return nil
|
||||
// }
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
rules := make(map[string]gvalid.RuleFunc, 3)
|
||||
rules["LENGTH_FIRST"] = LENGTH_FIRST
|
||||
rules["FIXED_LENGTH"] = FIXED_LENGTH
|
||||
rules["length"] = length
|
||||
g.Validator().RuleFuncMap(rules).Data(writedata).Run(gctx.New())
|
||||
// serializeslice[T](field, buf, writedata)
|
||||
} else {
|
||||
if err := binary.Write(buf, binary.BigEndian, writedata); err != nil {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DefaultPacketSerializer 默认序列化实现,使用大端序写入数据
|
||||
func DefaultPacketSerializer[T any]() PacketSerializer[T] {
|
||||
return func(data T) ([]byte, error) {
|
||||
var buf bytes.Buffer
|
||||
// 使用大端序写入数据
|
||||
// 1. 使用reflect获取结构体类型
|
||||
typ := reflect.TypeOf(data)
|
||||
fmt.Println("结构体类型名称:", typ.Name())
|
||||
fmt.Println("字段数量:", typ.NumField())
|
||||
|
||||
for i := 0; i < typ.NumField(); i++ {
|
||||
field := typ.Field(i)
|
||||
fmt.Printf("字段名: %s, 类型: %s",
|
||||
field.Name, field.Type)
|
||||
fmt.Println("字段值:", reflect.ValueOf(data).Field(i).Interface())
|
||||
|
||||
writedata := reflect.ValueOf(data).Field(i).Interface()
|
||||
fmt.Println(field.Type.Kind())
|
||||
|
||||
serializebase[T]( field, &buf, writedata)
|
||||
|
||||
}
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultPacketDeserializer 默认反序列化实现,使用大端序读取数据
|
||||
func DefaultPacketDeserializer[T any]() PacketDeserializer[T] {
|
||||
return func(data []byte) (T, error) {
|
||||
var result T
|
||||
reader := bytes.NewReader(data)
|
||||
// 使用大端序读取数据
|
||||
if err := binary.Read(reader, binary.BigEndian, &result); err != nil {
|
||||
var zero T
|
||||
return zero, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
}
|
||||
|
||||
// NewDefaultPacketHandler 创建默认的数据包处理句柄
|
||||
func NewDefaultPacketHandler[T any]() *PacketHandler[T] {
|
||||
return &PacketHandler[T]{
|
||||
Serialize: DefaultPacketSerializer[T](),
|
||||
Deserialize: DefaultPacketDeserializer[T](),
|
||||
}
|
||||
}
|
||||
|
||||
// 示例:使用自定义类型演示序列化与反序列化
|
||||
type ExampleData struct {
|
||||
ID int32
|
||||
Name string
|
||||
Data []byte
|
||||
}
|
||||
|
||||
// 自定义序列化函数(处理结构体类型)
|
||||
func CustomSerializer() PacketSerializer[ExampleData] {
|
||||
return func(data ExampleData) ([]byte, error) {
|
||||
var buf bytes.Buffer
|
||||
|
||||
// 先序列化基本类型字段
|
||||
if err := binary.Write(&buf, binary.BigEndian, data.ID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 序列化字符串长度和内容
|
||||
lenName := int32(len(data.Name))
|
||||
if err := binary.Write(&buf, binary.BigEndian, lenName); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err := buf.Write([]byte(data.Name)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 序列化字节数组长度和内容
|
||||
lenData := int32(len(data.Data))
|
||||
if err := binary.Write(&buf, binary.BigEndian, lenData); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err := buf.Write(data.Data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
}
|
||||
|
||||
// 自定义反序列化函数(处理结构体类型)
|
||||
func CustomDeserializer() PacketDeserializer[ExampleData] {
|
||||
return func(data []byte) (ExampleData, error) {
|
||||
var result ExampleData
|
||||
reader := bytes.NewReader(data)
|
||||
|
||||
// 读取基本类型字段
|
||||
if err := binary.Read(reader, binary.BigEndian, &result.ID); err != nil {
|
||||
return result, err
|
||||
}
|
||||
|
||||
// 读取字符串长度和内容
|
||||
var lenName int32
|
||||
if err := binary.Read(reader, binary.BigEndian, &lenName); err != nil {
|
||||
return result, err
|
||||
}
|
||||
if lenName > int32(reader.Len()) {
|
||||
return result, errors.New("invalid name length")
|
||||
}
|
||||
nameBuf := make([]byte, lenName)
|
||||
if _, err := reader.Read(nameBuf); err != nil {
|
||||
return result, err
|
||||
}
|
||||
result.Name = string(nameBuf)
|
||||
|
||||
// 读取字节数组长度和内容
|
||||
var lenData int32
|
||||
if err := binary.Read(reader, binary.BigEndian, &lenData); err != nil {
|
||||
return result, err
|
||||
}
|
||||
if lenData > int32(reader.Len()) {
|
||||
return result, errors.New("invalid data length")
|
||||
}
|
||||
result.Data = make([]byte, lenData)
|
||||
if _, err := reader.Read(result.Data); err != nil {
|
||||
return result, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user