package game import ( "encoding/json" "net/http" "reflect" "strconv" "strings" "github.com/gin-gonic/gin" "github.com/gorilla/websocket" ) type dataPack struct { Type int32 `json:"type"` Func string `json:"func"` Args []interface{} `json:"args"` } //CheckOrigin防止跨站点的请求伪造 var upGrader = websocket.Upgrader{ CheckOrigin: func(r *http.Request) bool { return true }, } func ping(c *gin.Context) { ws, err := upGrader.Upgrade(c.Writer, c.Request, nil) if err != nil { return } se := createEntity(ws) defer invokeFunc(se, "OnDestroy") defer ws.Close() invokeFunc(se, "OnLoad") for { _, message, err := ws.ReadMessage() if err != nil { break } dp := dataPack{} json.Unmarshal(message, &dp) invokeFuncByDataPack(se, &dp) } } type CreateEntity func(conn *websocket.Conn) interface{} var createEntity CreateEntity func StartServer(port int, path string, createEntityFunc CreateEntity) { createEntity = createEntityFunc r := gin.Default() r.GET(path, ping) r.Run(":" + strconv.Itoa(port)) } func SendPackFunction(ws *websocket.Conn, func_ string, args ...interface{}) { dp := dataPack{Func: func_, Args: args, Type: 1} ws.WriteJSON(&dp) } func invokeFunc(obj interface{}, func_ string, args ...interface{}) { ctx := reflect.ValueOf(obj) if strings.Contains(func_, ".") { func_Split := strings.Split(func_, ".") ctx = ctx.FieldByName(func_Split[0]) func_ = func_Split[1] } method := ctx.MethodByName(func_) if !method.IsValid() { return } argsLen := len(args) argsList := make([]reflect.Value, argsLen) for i := 0; i < argsLen; i++ { argsList[i] = reflect.ValueOf(args[i]) } method.Call(argsList) } //检测开关-在远程调用前是否进行合法检测 var CheckServiceFuncMapBeforInvoke = false //为了防止非法远程调用,只能调用Map中记录的方法 var ServiceFuncMap = make(map[string]bool) func invokeFuncByDataPack(obj interface{}, dp *dataPack) { if dp.Type == 1 { if !CheckServiceFuncMapBeforInvoke || ServiceFuncMap[dp.Func] { invokeFunc(obj, dp.Func, dp.Args...) } } }