一波更新

This commit is contained in:
tangping
2025-01-23 16:12:49 +08:00
parent 22ac6c1fed
commit 5f3a40a50e
90 changed files with 2392 additions and 1791 deletions

View File

@@ -0,0 +1,218 @@
package webServer
import (
"encoding/json"
"fmt"
"goutil/jsonUtil"
"goutil/logUtilPlus"
"goutil/typeUtil"
"goutil/zlibUtil"
"io"
"net/http"
)
// ApiContext
// @description: Api请求上下文对象
type ApiContext struct {
// 请求对象
request *http.Request
// 应答写对象
responseWriter http.ResponseWriter
// 请求数据
requestBytes []byte
// 字典形式的请求数据
requestDataByMap typeUtil.MapData
//获取头部信息
header *http.Header
}
// GetRequest
// @description: 获取请求对象
// parameter:
// @receiver this: this
// return:
// @*http.Request: 请求对象
func (this *ApiContext) GetRequest() *http.Request {
return this.request
}
// GetResponseWriter
// @description: 获取应答写对象
// parameter:
// @receiver this: this
// return:
// @http.ResponseWriter: 应答写对象
func (this *ApiContext) GetResponseWriter() http.ResponseWriter {
return this.responseWriter
}
// GetRequestBytes
// @description: 获取请求字节数据
// parameter:
// @receiver this: this
// return:
// @[]byte: 请求字节数组
func (this *ApiContext) GetRequestBytes() []byte {
return this.requestBytes
}
// readContent
// @description: 读取内容
// parameter:
// @receiver this: this 请求对象
// @isZlib: 是否数据压缩
// return:
// @content: 二进制格式的内容
// @err: 错误对象
func (this *ApiContext) readContent(isZlib bool) (content []byte, err error) {
var buffer []byte
defer this.request.Body.Close()
if buffer, err = io.ReadAll(this.request.Body); err != nil {
logUtilPlus.ErrorLog(fmt.Sprintf("url:%s,读取数据出错,错误信息为:%s", this.request.RequestURI, err))
return
}
// 不压缩,则直接返回
if isZlib == false {
this.requestBytes = buffer
logUtilPlus.ErrorLog(fmt.Sprintf("buffer=%v", buffer))
return buffer, err
}
// 解压数据
if content, err = zlibUtil.Decompress(buffer); err != nil {
logUtilPlus.ErrorLog(fmt.Sprintf("url:%s,解压缩数据出错,错误信息为:%s", this.request.RequestURI, err))
return
}
this.requestBytes = content
return
}
// Unmarshal
// @description: 反序列化
// parameter:
// @receiver this: this
// @obj: 反序列化结果数据
// return:
// @error: 反序列化错误数据
func (this *ApiContext) Unmarshal(obj interface{}) error {
contentData := this.GetRequestBytes()
var errMsg error
// 反序列化
if obj, errMsg = json.Marshal(contentData); errMsg != nil {
logUtilPlus.ErrorLog(fmt.Sprintf("反序列化%s出错错误信息为%s", string(contentData), errMsg.Error()))
return errMsg
}
return nil
}
// RequestDataByMap
// @description: 获取请求的map格式数据
// parameter:
// @receiver this: this
// return:
// @typeUtil.MapData: map数据
// @error: 错误信息
func (this *ApiContext) RequestDataByMap() (typeUtil.MapData, error) {
if this.requestDataByMap != nil {
return this.requestDataByMap, nil
}
var data typeUtil.MapData
if err := this.Unmarshal(&data); err != nil {
return nil, err
}
this.requestDataByMap = data
return this.requestDataByMap, nil
}
// RequestDataBySlice
// @description: 获取请求的slice格式数据
// parameter:
// @receiver this: this
// return:
// @[]interface{}: 返回的数组数据
func (this *ApiContext) RequestDataBySlice() []interface{} {
result := make([]interface{}, 0, 8)
for _, value := range this.requestDataByMap {
result = append(result, value)
}
return result
}
// RequestDataBySlice2
// @description: 获取请求的slice格式数据
// parameter:
// @receiver this: this
// return:
// @[]interface{}: 返回的数组数据
// @error:
func (this *ApiContext) RequestDataBySlice2() (interface{}, error) {
contentData := this.GetRequestBytes()
// 反序列化
var result interface{}
var errMsg error
if result, errMsg = jsonUtil.UnMarshalWithNumberType(string(contentData)); errMsg != nil {
logUtilPlus.ErrorLog(fmt.Sprintf("用[]interface{}反序列化%s出错错误信息为%s", string(contentData), errMsg.Error()))
return nil, errMsg
}
return result, nil
}
// RequestDataBySlice2ByJson
// @description: 获取请求的slice格式数据
// parameter:
// @receiver this: this
// return:
// @[]interface{}: 返回的数组数据
// @error:
func (this *ApiContext) RequestDataBySlice2ByJson() ([]interface{}, error) {
contentData := this.GetRequestBytes()
// 反序列化
result := make([]interface{}, 0, 8)
if errMsg := json.Unmarshal(contentData, &result); errMsg != nil {
logUtilPlus.ErrorLog(fmt.Sprintf("用[]interface{}反序列化%s出错错误信息为%s", string(contentData), errMsg.Error()))
return nil, errMsg
}
return result, nil
}
// NewApiContext
// @description: 新建API上下文对象
// parameter:
// @_request: 请求对象
// @_responseWriter: 应答写对象
// @isZlib: 数据是否压缩
// return:
// @*ApiContext: 上下文
// @error: 错误信息
func NewApiContext(_request *http.Request, _responseWriter http.ResponseWriter, isZlib bool) (*ApiContext, error) {
context := &ApiContext{
request: _request,
header: &_request.Header,
responseWriter: _responseWriter,
}
// 读取数据
_, errMsg := context.readContent(isZlib)
if errMsg != nil {
return nil, errMsg
}
return context, nil
}

View File

@@ -0,0 +1,112 @@
package webServer
import (
"net/http"
"common/resultStatus"
)
// 处理函数
type HandleFunc func(context *ApiContext) *ResponseObject
// ApiHandler
//
// @description: API处理结构
type ApiHandler struct {
// API完整路径名称
apiFullName string
// 方法定义
handleFun HandleFunc
// 方法参数名称集合
funcParamNames []string
}
// ApiFullName
//
// @description: API完整路径名称
//
// parameter:
//
// @receiver this: this
//
// return:
//
// @string:
func (this *ApiHandler) ApiFullName() string {
return this.apiFullName
}
// HandleFun
//
// @description: 方法定义
//
// parameter:
//
// @receiver this: this
//
// return:
//
// @HandleFunc: 方法
func (this *ApiHandler) HandleFun() HandleFunc {
return this.handleFun
}
// FuncParamNames
//
// @description: 方法参数名称集合
//
// parameter:
//
// @receiver this: this
//
// return:
//
// @[]string: 方法参数名称集合
func (this *ApiHandler) FuncParamNames() []string {
return this.funcParamNames
}
// CheckParam
//
// @description: 检测参数数量
//
// parameter:
//
// @receiver this: this
// @r:
//
// return:
//
// @resultstatus.ResultStatus: 状态码数据
func (this *ApiHandler) CheckParam(r *http.Request) resultStatus.ResultStatus {
for _, name := range this.funcParamNames {
if r.Form[name] == nil || len(r.Form[name]) == 0 {
return resultStatus.APIParamError
}
}
return resultStatus.Success
}
// newApiHandler
//
// @description: 创建新的请求方法对象
//
// parameter:
//
// @_apiFullName: API完整路径名称
// @_funcDefinition: 方法定义
// @_funcParamNames: 方法参数名称集合
//
// return:
//
// @*ApiHandler: 请求方法对象
func newApiHandler(_apiFullName string, _funcDefinition HandleFunc, _funcParamNames ...string) *ApiHandler {
return &ApiHandler{
apiFullName: _apiFullName,
handleFun: _funcDefinition,
funcParamNames: _funcParamNames,
}
}

View File

@@ -0,0 +1,69 @@
package webServer
import (
"fmt"
"net/http"
)
var (
// 处理方法集合
// Key:API名
handlerData = make(map[string]*ApiHandler)
// 文档方法
remarkFunc func(w http.ResponseWriter, r *http.Request)
)
// RegisterRemarkFunc
//
// @description: 注册文档api方法
//
// parameter:
//
// @_remarkFunc: _remarkFunc
//
// return:
func RegisterRemarkFunc(_remarkFunc func(w http.ResponseWriter, r *http.Request)) {
remarkFunc = _remarkFunc
}
// RegisterHandleFunc
//
// @description: 注册处理方法
//
// parameter:
//
// @apiName: API名称
// @callback: 回调方法
// @paramNames: 参数名称集合
//
// return:
func RegisterHandleFunc(apiName string, callback HandleFunc, paramNames ...string) {
apiFullName := fmt.Sprintf("/API/%s", apiName)
if _, exist := handlerData[apiFullName]; exist {
panic(fmt.Errorf("重复注册处理函数:%s", apiFullName))
}
handlerData[apiFullName] = newApiHandler(apiFullName, callback, paramNames...)
}
// GetHandleFunc
//
// @description: 获取请求方法
//
// parameter:
//
// @apiFullName: 方法名称
//
// return:
//
// @*ApiHandler: 请求方法
// @bool: 是否存在
func GetHandleFunc(apiFullName string) (*ApiHandler, bool) {
if requestFuncObj, exists := handlerData[apiFullName]; exists {
return requestFuncObj, exists
}
return nil, false
}

View File

@@ -0,0 +1,436 @@
package webServer
import (
config "common/configsYaml"
"common/resultStatus"
"goutil/logUtilPlus"
"reflect"
"strconv"
"strings"
)
const (
// 供客户端访问的模块的后缀
con_ModuleSuffix = "Module"
// 定义用于分隔模块名称和方法名称的分隔符
con_DelimeterOfObjAndMethod = "_"
)
var (
// 定义存放所有方法映射的变量
methodMap = make(map[string]*methodAndInOutTypes)
// 函数返回值类型
responseType reflect.Type = reflect.TypeOf(new(ResponseObject))
)
// getStructName
//
// @description: 获取结构体类型的名称
//
// parameter:
//
// @structType: 结构体类型
//
// return:
//
// @string: 结构体类型的名称
func getStructName(structType reflect.Type) string {
reflectTypeStr := structType.String()
reflectTypeArr := strings.Split(reflectTypeStr, ".")
return reflectTypeArr[len(reflectTypeArr)-1]
}
// getFullModuleName
//
// @description: 获取完整的模块名称
//
// parameter:
//
// @moduleName: 模块名称
//
// return:
//
// @string: 完整的模块名称
func getFullModuleName(moduleName string) string {
return moduleName + con_ModuleSuffix
}
// getFullMethodName
//
// @description: 获取完整的方法名称
//
// parameter:
//
// @structName: 结构体名称
// @methodName: 方法名称
//
// return:
//
// @string: 完整的方法名称
func getFullMethodName(structName, methodName string) string {
return structName + con_DelimeterOfObjAndMethod + methodName
}
// resolveMethodInOutParams
//
// @description: 解析方法的输入输出参数
//
// parameter:
//
// @method: 方法对应的反射值
//
// return:
//
// @inTypes: 输入参数类型集合
// @outTypes: 输出参数类型集合
func resolveMethodInOutParams(method reflect.Value) (inTypes []reflect.Type, outTypes []reflect.Type) {
methodType := method.Type()
for i := 0; i < methodType.NumIn(); i++ {
inTypes = append(inTypes, methodType.In(i))
}
for i := 0; i < methodType.NumOut(); i++ {
outTypes = append(outTypes, methodType.Out(i))
}
return
}
// RegisterFunction
//
// @description: 将需要对客户端提供方法的对象进行注册
//
// parameter:
//
// @structObject: 对象
//
// return:
func RegisterFunction(structObject interface{}) {
// 获取structObject对应的反射 Type 和 Value
reflectValue := reflect.ValueOf(structObject)
reflectType := reflect.TypeOf(structObject)
// 提取对象类型名称
structName := getStructName(reflectType)
// 获取structObject中返回值为responseObject的方法
for i := 0; i < reflectType.NumMethod(); i++ {
// 获得方法名称
methodName := reflectType.Method(i).Name
// 获得方法及其输入参数的类型列表
method := reflectValue.MethodByName(methodName)
inTypes, outTypes := resolveMethodInOutParams(method)
// 判断输出参数数量是否正确
if len(outTypes) != 1 {
continue
}
// 判断返回值是否为responseObject
if outTypes[0] != responseType {
continue
}
// 添加到列表中
methodMap[getFullMethodName(structName, methodName)] = newmethodAndInOutTypes(method, inTypes, outTypes)
}
}
// CallFunction
//
// @description: 调用方法
//
// parameter:
//
// @requestObj: 客户端对象
//
// return:
//
// @responseObj: 请求对象
func CallFunction(requestObj *RequestObject) (responseObj *ResponseObject) {
responseObj = GetInitResponseObj()
var methodAndInOutTypes *methodAndInOutTypes
var ok bool
// 根据传入的ModuleName和MethodName找到对应的方法对象
key := getFullMethodName(requestObj.ModuleName, requestObj.MethodName)
if methodAndInOutTypes, ok = methodMap[key]; !ok {
logUtilPlus.ErrorLog("找不到指定的方法:%s", key)
responseObj.SetResultStatus(resultStatus.NotSpecificMethod)
return
}
// 判断参数数量是否相同
inTypesLength := len(methodAndInOutTypes.InTypes)
paramLength := len(requestObj.Parameters)
if paramLength != inTypesLength {
logUtilPlus.ErrorLog("传入的参数数量不符,本地方法%s的参数数量%d传入的参数数量为%d", key, inTypesLength, paramLength)
responseObj.SetResultStatus(resultStatus.ParamNotMatch)
return
}
// 构造参数
in := make([]reflect.Value, inTypesLength)
for i := 0; i < inTypesLength; i++ {
inTypeItem := methodAndInOutTypes.InTypes[i]
paramItem := requestObj.Parameters[i]
// 已支持类型Client,Player(非基本类型)
// 已支持类型Bool,Int,Int8,Int16,Int32,Int64,Uint,Uint8,Uint16,Uint32,Uint64,Float32,Float64,String
// 已支持类型以及上面所列出类型的Slice类型
// 未支持类型Uintptr,Complex64,Complex128,Array,Chan,Func,Interface,Map,Ptr,Struct,UnsafePointer
// 由于byte与int8同义rune与int32同义所以并不需要单独处理
// 枚举参数的类型,并进行类型转换
switch inTypeItem.Kind() {
case reflect.Bool:
if paramBool, ok := paramItem.(bool); ok {
in[i] = reflect.ValueOf(paramBool)
}
case reflect.Int:
if paramInt, ok := paramItem.(int); ok {
in[i] = reflect.ValueOf(int(paramInt))
}
case reflect.Int8:
if paramInt8, ok := paramItem.(float64); ok {
in[i] = reflect.ValueOf(int8(paramInt8))
}
case reflect.Int16:
if paramInt16, ok := paramItem.(float64); ok {
in[i] = reflect.ValueOf(int16(paramInt16))
}
case reflect.Int32:
if paramInt32, ok := paramItem.(int32); ok {
in[i] = reflect.ValueOf(paramInt32)
} else if paramFloat64, ok := paramItem.(float64); ok {
in[i] = reflect.ValueOf(int32(paramFloat64))
}
case reflect.Int64:
if paramInt64, ok := paramItem.(int64); ok {
in[i] = reflect.ValueOf(paramInt64)
} else if paramUint64, ok := paramItem.(uint64); ok {
in[i] = reflect.ValueOf(int64(paramUint64))
} else if paramString, ok := paramItem.(string); ok {
i64, err := strconv.ParseInt(paramString, 10, 64)
if err == nil {
in[i] = reflect.ValueOf(i64)
}
} else if paramFloat64, ok := paramItem.(float64); ok {
in[i] = reflect.ValueOf(int64(paramFloat64))
}
case reflect.Uint:
if paramUint, ok := paramItem.(float64); ok {
in[i] = reflect.ValueOf(uint(paramUint))
}
case reflect.Uint8:
if paramUint8, ok := paramItem.(uint8); ok {
in[i] = reflect.ValueOf(uint8(paramUint8))
}
case reflect.Uint16:
if paramUint16, ok := paramItem.(uint16); ok {
in[i] = reflect.ValueOf(uint16(paramUint16))
}
case reflect.Uint32:
if paramUint32, ok := paramItem.(float64); ok {
in[i] = reflect.ValueOf(uint32(paramUint32))
}
case reflect.Uint64:
if paramUint64, ok := paramItem.(float64); ok {
in[i] = reflect.ValueOf(uint64(paramUint64))
}
case reflect.Float32:
if paramFloat32, ok := paramItem.(float64); ok {
in[i] = reflect.ValueOf(float32(paramFloat32))
}
case reflect.Float64:
if paramFloat64, ok := paramItem.(float64); ok {
in[i] = reflect.ValueOf(paramFloat64)
}
case reflect.String:
if paramString, ok := paramItem.(string); ok {
in[i] = reflect.ValueOf(paramString)
}
case reflect.Slice:
// 如果是Slice类型则需要对其中的项再次进行类型判断及类型转换
if param_interface, ok := paramItem.([]interface{}); ok {
switch inTypeItem.String() {
case "[]bool":
params_inner := make([]bool, len(param_interface), len(param_interface))
for i := 0; i < len(param_interface); i++ {
if param_bool, ok := param_interface[i].(bool); ok {
params_inner[i] = param_bool
}
}
in[i] = reflect.ValueOf(params_inner)
case "[]int":
params_inner := make([]int, len(param_interface), len(param_interface))
for i := 0; i < len(param_interface); i++ {
if param_float64, ok := param_interface[i].(int); ok {
params_inner[i] = int(param_float64)
}
}
in[i] = reflect.ValueOf(params_inner)
case "[]int8":
params_inner := make([]int8, len(param_interface), len(param_interface))
for i := 0; i < len(param_interface); i++ {
if param_float64, ok := param_interface[i].(float64); ok {
params_inner[i] = int8(param_float64)
}
}
in[i] = reflect.ValueOf(params_inner)
case "[]int16":
params_inner := make([]int16, len(param_interface), len(param_interface))
for i := 0; i < len(param_interface); i++ {
if param_float64, ok := param_interface[i].(float64); ok {
params_inner[i] = int16(param_float64)
}
}
in[i] = reflect.ValueOf(params_inner)
case "[]int32":
params_inner := make([]int32, len(param_interface), len(param_interface))
for i := 0; i < len(param_interface); i++ {
param_float64, ok := param_interface[i].(int32)
if ok {
params_inner[i] = int32(param_float64)
continue
} else {
param_int16, right := param_interface[i].(uint16)
if right == true {
params_inner[i] = int32(param_int16)
}
}
}
in[i] = reflect.ValueOf(params_inner)
case "[]int64":
params_inner := make([]int64, len(param_interface), len(param_interface))
for i := 0; i < len(param_interface); i++ {
if param_float64, ok := param_interface[i].(int64); ok {
params_inner[i] = int64(param_float64)
} else if param_uint64, ok := param_interface[i].(uint64); ok {
params_inner[i] = int64(param_uint64)
} else if param_string, ok := param_interface[i].(string); ok {
i64, err := strconv.ParseInt(param_string, 10, 64)
if err == nil {
params_inner[i] = i64
}
}
}
in[i] = reflect.ValueOf(params_inner)
case "[]uint":
params_inner := make([]uint, len(param_interface), len(param_interface))
for i := 0; i < len(param_interface); i++ {
if param_float64, ok := param_interface[i].(uint); ok {
params_inner[i] = uint(param_float64)
}
}
in[i] = reflect.ValueOf(params_inner)
// case "[]uint8": 特殊处理
case "[]uint16":
params_inner := make([]uint16, len(param_interface), len(param_interface))
for i := 0; i < len(param_interface); i++ {
if param_float64, ok := param_interface[i].(uint16); ok {
params_inner[i] = uint16(param_float64)
}
}
in[i] = reflect.ValueOf(params_inner)
case "[]uint32":
params_inner := make([]uint32, len(param_interface), len(param_interface))
for i := 0; i < len(param_interface); i++ {
if param_float64, ok := param_interface[i].(uint32); ok {
params_inner[i] = uint32(param_float64)
}
}
in[i] = reflect.ValueOf(params_inner)
case "[]uint64":
params_inner := make([]uint64, len(param_interface), len(param_interface))
for i := 0; i < len(param_interface); i++ {
if param_float64, ok := param_interface[i].(uint64); ok {
params_inner[i] = uint64(param_float64)
}
}
in[i] = reflect.ValueOf(params_inner)
case "[]float32":
params_inner := make([]float32, len(param_interface), len(param_interface))
for i := 0; i < len(param_interface); i++ {
if param_float64, ok := param_interface[i].(float64); ok {
params_inner[i] = float32(param_float64)
}
}
in[i] = reflect.ValueOf(params_inner)
case "[]float64":
params_inner := make([]float64, len(param_interface), len(param_interface))
for i := 0; i < len(param_interface); i++ {
if param_float64, ok := param_interface[i].(float64); ok {
params_inner[i] = param_float64
}
}
in[i] = reflect.ValueOf(params_inner)
case "[]string":
params_inner := make([]string, len(param_interface), len(param_interface))
for i := 0; i < len(param_interface); i++ {
if param_string, ok := param_interface[i].(string); ok {
params_inner[i] = param_string
}
}
in[i] = reflect.ValueOf(params_inner)
}
} else if inTypeItem.String() == "[]uint8" { // 由于[]uint8在传输过程中会被转化成字符串所以单独处理;
if param_string, ok := paramItem.(string); ok {
param_uint8 := ([]uint8)(param_string)
in[i] = reflect.ValueOf(param_uint8)
}
}
case reflect.Pointer:
//if paramStruct, ok := paramItem.(struct{}); ok {
// in[i] = reflect.ValueOf(paramStruct)
//}
in[i] = reflect.ValueOf(paramItem)
}
}
// 判断是否有无效的参数(传入的参数类型和方法定义的类型不匹配导致没有赋值)
for _, item := range in {
if reflect.Value.IsValid(item) == false {
logUtilPlus.ErrorLog("type:%v,value:%v.方法%s传入的参数%v无效", reflect.TypeOf(item), reflect.ValueOf(item), key, requestObj.Parameters)
responseObj.SetResultStatus(resultStatus.ParamInValid)
return
}
}
// 传入参数,调用方法
if config.DEBUG {
if requestObj.MethodName != "GetRefreshData" {
logUtilPlus.DebugLog("Begin Call Func:module:%v, method:%v,inParams:%v\n\n", requestObj.ModuleName, requestObj.MethodName, in)
}
}
out := methodAndInOutTypes.Method.Call(in)
if config.DEBUG {
if requestObj.MethodName != "GetRefreshData" {
for i, v := range in {
logUtilPlus.DebugLog("\nparams %v,%v\n", i, v)
}
}
}
// 并输出结果到客户端由于只有一个返回值所以取out[0]
if responseObj, ok = (&out[0]).Interface().(*ResponseObject); !ok {
logUtilPlus.ErrorLog("返回值类型推断为ResponseObject 出错, tyep is :%v", reflect.TypeOf(out[0]))
responseObj.SetResultStatus(resultStatus.ParamInValid)
return
}
if config.DEBUG {
if requestObj.MethodName != "GetRefreshData" {
logUtilPlus.DebugLog("返回数据:code:%v, data:%v, mess:%v\n\n", responseObj.Code, responseObj.Value, responseObj.Message)
}
}
return
}

View File

@@ -0,0 +1,40 @@
package webServer
import (
"reflect"
)
// methodAndInOutTypes
//
// @description: 反射的方法和输入、输出参数类型组合类型
type methodAndInOutTypes struct {
// 反射出来的对应方法对象
Method reflect.Value
// 反射出来的方法的输入参数的类型集合
InTypes []reflect.Type
// 反射出来的方法的输出参数的类型集合
OutTypes []reflect.Type
}
// newmethodAndInOutTypes
//
// @description: newmethodAndInOutTypes
//
// parameter:
//
// @_method: _method
// @_inTypes: _inTypes
// @_outTypes: _outTypes
//
// return:
//
// @*methodAndInOutTypes: methodAndInOutTypes
func newmethodAndInOutTypes(_method reflect.Value, _inTypes []reflect.Type, _outTypes []reflect.Type) *methodAndInOutTypes {
return &methodAndInOutTypes{
Method: _method,
InTypes: _inTypes,
OutTypes: _outTypes,
}
}

View File

@@ -0,0 +1,37 @@
package webServer
// RequestObject
//
// @description: 请求对象
type RequestObject struct {
// 以下属性是由客户端直接传入的,可以直接反序列化直接得到的
// 请求的模块名称
ModuleName string
// 请求的方法名称
MethodName string
// 请求的参数数组
Parameters []interface{}
}
// NewRequestObject
//
// @description: NewRequestObject
//
// parameter:
//
// @_ModuleName: _ModuleName
// @_MethodName: _MethodName
// @_Parameters: _Parameters
//
// return:
//
// @*RequestObject: RequestObject
func NewRequestObject(_ModuleName string, _MethodName string, _Parameters []interface{}) *RequestObject {
return &RequestObject{
ModuleName: _ModuleName,
MethodName: _MethodName,
Parameters: _Parameters,
}
}

View File

@@ -0,0 +1,83 @@
package webServer
import (
"common/resultStatus"
)
// ResponseObject
// @description: 响应对象
type ResponseObject struct {
// 响应结果的状态值
Code resultStatus.StatusCode
// Status 状态
Status int32
// 响应结果的状态值所对应的描述信息
Message string
// 响应结果的数据
Value interface{}
}
// SetResultStatus
// @description: 设置响应结果的状态值
// parameter:
// @receiver this: this
// @rs: 响应结果的状态值
// return:
// @*ResponseObject: 响应结果对象
func (this *ResponseObject) SetResultStatus(rs resultStatus.ResultStatus) *ResponseObject {
this.Code = rs.Code()
this.Message = rs.Message()
return this
}
// SetData
// @description: 设置响应对象数据
// parameter:
// @receiver this: this
// @data: 响应结果的数据
// return:
// @*ResponseObject: 响应结果对象
func (this *ResponseObject) SetData(data interface{}) *ResponseObject {
this.Value = data
return this
}
// IsSuccess
// @description: 是否是请求成功
// parameter:
// @receiver this:this
// return:
// @bool:是请求成功
func (this *ResponseObject) IsSuccess() bool {
return this.Code == resultStatus.Success.Code()
}
// SetCodeStatus
// @description: 同步code和status状态
// parameter:
// @receiver this:this
// return:
func (this *ResponseObject) SetCodeStatus() {
if this.Code == resultStatus.Success.Code() && resultStatus.StatusCode(this.Status) != resultStatus.Success.Code() {
this.Code = resultStatus.StatusCode(this.Status)
}
return
}
// GetInitResponseObj
// @description: 获取初始的响应对象
// parameter:
// return:
// @*ResponseObject: 响应对象
func GetInitResponseObj() *ResponseObject {
return &ResponseObject{
Code: resultStatus.Success.Code(),
Message: "",
Value: nil,
}
}

View File

@@ -0,0 +1,43 @@
package webServer
import (
"encoding/json"
"fmt"
"goutil/logUtilPlus"
"net/http"
"strconv"
)
// responseResult
// @description: responseResult
// parameter:
// @w: w
// @responseObj: responseObj
// return:
func responseResult(w http.ResponseWriter, responseObj *ResponseObject) {
b, err := json.Marshal(responseObj)
if err != nil {
logUtilPlus.ErrorLog(fmt.Sprintf("序列化输出结果%v出错", responseObj))
return
}
w.Header().Add("Content-Length", strconv.Itoa(len(b)))
w.Write(b)
}
// responseResultByJson
// @description: responseResult
// parameter:
// @w: w
// @responseObj: responseObj
// return:
func responseResultByJson(w http.ResponseWriter, responseObj *ResponseObject) {
b, err := json.Marshal(responseObj)
if err != nil {
logUtilPlus.ErrorLog(fmt.Sprintf("序列化输出结果%v出错", responseObj))
return
}
w.Header().Add("Content-Length", strconv.Itoa(len(b)))
w.Write(b)
}

View File

@@ -0,0 +1,133 @@
package webServer
import (
config "common/configsYaml"
"common/resultStatus"
"common/utils"
"encoding/json"
"fmt"
"framework/ipMgr"
"goutil/logUtilPlus"
"goutil/stringUtil"
"goutil/webUtil"
"net/http"
"strings"
)
// selfDefineMux
//
// @description: 定义自定义的Mux对象
type selfDefineMux struct {
}
// ServeHTTP
//
// @description: ServeHTTP
//
// parameter:
//
// @receiver mux: mux
// @w: w
// @r: r
//
// return:
func (mux *selfDefineMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
responseObj := GetInitResponseObj()
defer utils.LogReqErrorRecover(r)
// 判断是否是接口文档
if strings.Contains(r.RequestURI, "Remarks") && r.Method == "GET" {
remarkFunc(w, r)
return
}
// 判断是否是POST方法
if r.Method != "POST" {
responseResult(w, responseObj.SetResultStatus(resultStatus.OnlySupportPOST))
return
}
// 验证IP是否正确
if config.DEBUG == false && ipMgr.IsIpValid(webUtil.GetRequestIP(r)) == false {
logUtilPlus.ErrorLog(fmt.Sprintf("请求的IP%s无效", webUtil.GetRequestIP(r)))
responseResult(w, responseObj.SetResultStatus(resultStatus.IPForbid))
return
}
// 构造contex
context, errMsg := NewApiContext(r, w, false)
if errMsg != nil {
// 输出结果
responseResult(w, responseObj.SetResultStatus(resultStatus.APIDataError))
return
}
// 根据路径选择不同的处理方法
if handlerFunObj, exists := GetHandleFunc(r.RequestURI); exists {
defer func() {
if config.DEBUG {
b, _ := json.Marshal(responseObj)
msg := fmt.Sprintf("API:%v 请求数据:%v;返回数据:%s;",
r.RequestURI, string(context.GetRequestBytes()), string(b))
logUtilPlus.DebugLog(msg)
}
}()
// 输出结果
responseObj := handlerFunObj.HandleFun()(context)
responseResult(w, responseObj)
return
}
// 通过反射选择不同的方法
strs := stringUtil.Split(r.RequestURI, []string{"/"})
var params []interface{}
var err error
isJson := false
// 参数错误
if len(strs) != 2 {
responseResult(w, responseObj.SetResultStatus(resultStatus.APIDataError))
return
}
params, err = context.RequestDataBySlice2ByJson()
if err != nil {
responseResult(w, responseObj.SetResultStatus(resultStatus.APIDataError))
return
}
//验证是否登录
if !IsSkipVerifyTokenPage(strs[0], strs[1]) {
tokenStr := context.header.Get("token")
// token 转型成 int64
token := stringUtil.StringToInt64(tokenStr)
//是否存在
exist, tokenData := CheckToken(token)
if !exist {
responseResult(w, responseObj.SetResultStatus(resultStatus.NotLogin))
return
}
//添加登录用户到参数里的第一个
params = append([]interface{}{tokenData.UserInfo}, params...)
}
//是否需要请求信息
if IsNeedGetRequestInfo(strs[0], strs[1]) {
//添加请求信息到最后一个参数
params = append(params, r)
}
resquestData := NewRequestObject(strs[0], strs[1], params)
resp := CallFunction(resquestData)
if isJson {
responseResultByJson(w, resp)
} else {
responseResult(w, resp)
}
}

View File

@@ -0,0 +1,41 @@
package webServer
import (
"fmt"
"net/http"
"sync"
"goutil/logUtil"
"goutil/logUtilPlus"
"net/http/pprof"
config "common/configsYaml"
)
// Start
// @description: 启动服务器
// parameter:
// @wg: WaitGroup对象
// return:
func Start(wg *sync.WaitGroup) {
defer func() {
wg.Done()
}()
// 启动过程中不需要捕获异常
logUtilPlus.PrintAndWriteLog(logUtil.Warn, fmt.Sprintf("Web服务器开始监听:%v", config.ConfigYaml.Root.WebServerAddress))
// 启动Web服务器监听
mux := http.NewServeMux()
mux.Handle("/", &selfDefineMux{})
mux.HandleFunc("/debug/pprof/", pprof.Index)
mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
err := http.ListenAndServe(config.ConfigYaml.Root.WebServerAddress, mux)
if err != nil {
panic(fmt.Errorf("ListenAndServe失败错误信息为%s", err))
}
}

View File

@@ -0,0 +1,129 @@
package webServer
import (
"sync"
"time"
)
var (
//已经登录的用户
loginUserMap = make(map[int64]*TokenInfo)
//锁
lock sync.RWMutex
//跳过验证token的页面
skipVerifyTokenPage = make(map[string]bool)
//需要获取请求信息
needGetRequestInfo = make(map[string]bool)
)
type TokenInfo struct {
//管理员id
Id int64
//管理员账号
Account string
//登录用户缓存
UserInfo any
//过期时间
ExpireTime time.Time
}
// AddLoginUserToken 添加登录用户及其令牌信息到缓存中
// 参数:
//
// token: 用户的登录令牌
// tokenInfo: 令牌的详细信息,包括过期时间等
func AddLoginUserToken(token int64, tokenInfo *TokenInfo) {
//添加锁防止并发
lock.Lock()
defer lock.Unlock()
// 默认24小时过期
tokenInfo.ExpireTime = time.Now().Add(time.Hour * 24)
//移除旧的令牌
for tokenKey, tokenInfoValue := range loginUserMap {
if tokenInfo.Id == tokenInfoValue.Id {
delete(loginUserMap, tokenKey)
}
}
// 将令牌与用户信息添加到全局的登录用户映射中
loginUserMap[token] = tokenInfo
}
// CheckToken 检查令牌是否有效
// 参数:
//
// token: 需要检查的令牌字符串
//
// 返回值:
//
// bool: 表示令牌是否有效的布尔值true表示有效false表示无效
func CheckToken(token int64) (bool, *TokenInfo) {
//添加锁防止并发
lock.Lock()
defer lock.Unlock()
// 获取当前时间
now := time.Now()
// 获取令牌对应的用户信息
tokenInfo, ok := loginUserMap[token]
if !ok {
// 如果没有找到对应的用户信息,则令牌无效
return false, nil
}
// 获取令牌过期时间
expireTime := tokenInfo.ExpireTime
// 如果令牌过期时间早于当前时间,则令牌无效
if expireTime.Before(now) {
//移除令牌
delete(loginUserMap, token)
return false, nil
}
//如果生效的话,则更新过期时间
tokenInfo.ExpireTime = now.Add(time.Hour * 24)
return true, tokenInfo
}
// AddSkipVerifyTokenPage 添加跳过验证token的页面
func AddSkipVerifyTokenPage(moduleName, methodName string) {
skipVerifyTokenPage[moduleName+"_"+methodName] = true
}
// IsSkipVerifyTokenPage 判断是否跳过验证token的页面
func IsSkipVerifyTokenPage(moduleName, methodName string) bool {
exist, ok := skipVerifyTokenPage[moduleName+"_"+methodName]
if !exist {
return false
}
return ok
}
// AddNeedGetRequestInfo 添加需要获取请求信息的页面
func AddNeedGetRequestInfo(moduleName, methodName string) {
needGetRequestInfo[moduleName+"_"+methodName] = true
}
// IsNeedGetRequestInfo 判断是否需要获取请求信息的页面
func IsNeedGetRequestInfo(moduleName, methodName string) bool {
exist, ok := needGetRequestInfo[moduleName+"_"+methodName]
if !exist {
return false
}
return ok
}