server.go 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. package game
  2. import (
  3. "encoding/json"
  4. "net/http"
  5. "reflect"
  6. "strconv"
  7. "strings"
  8. "github.com/gin-gonic/gin"
  9. "github.com/gorilla/websocket"
  10. )
  11. type dataPack struct {
  12. Type int32 `json:"type"`
  13. Func string `json:"func"`
  14. Args []interface{} `json:"args"`
  15. }
  16. //CheckOrigin防止跨站点的请求伪造
  17. var upGrader = websocket.Upgrader{
  18. CheckOrigin: func(r *http.Request) bool {
  19. return true
  20. },
  21. }
  22. func ping(c *gin.Context) {
  23. ws, err := upGrader.Upgrade(c.Writer, c.Request, nil)
  24. if err != nil {
  25. return
  26. }
  27. se := createEntity(ws)
  28. defer invokeFunc(se, "OnDestroy")
  29. defer ws.Close()
  30. invokeFunc(se, "OnLoad")
  31. for {
  32. _, message, err := ws.ReadMessage()
  33. if err != nil {
  34. break
  35. }
  36. dp := dataPack{}
  37. json.Unmarshal(message, &dp)
  38. invokeFuncByDataPack(se, &dp)
  39. }
  40. }
  41. type CreateEntity func(conn *websocket.Conn) interface{}
  42. var createEntity CreateEntity
  43. func StartServer(port int, path string, createEntityFunc CreateEntity) {
  44. createEntity = createEntityFunc
  45. r := gin.Default()
  46. r.GET(path, ping)
  47. r.Run(":" + strconv.Itoa(port))
  48. }
  49. func SendPackFunction(ws *websocket.Conn, func_ string, args ...interface{}) {
  50. dp := dataPack{Func: func_, Args: args, Type: 1}
  51. ws.WriteJSON(&dp)
  52. }
  53. func invokeFunc(obj interface{}, func_ string, args ...interface{}) {
  54. ctx := reflect.ValueOf(obj)
  55. if strings.Contains(func_, ".") {
  56. func_Split := strings.Split(func_, ".")
  57. ctx = ctx.FieldByName(func_Split[0])
  58. func_ = func_Split[1]
  59. }
  60. method := ctx.MethodByName(func_)
  61. if !method.IsValid() {
  62. return
  63. }
  64. argsLen := len(args)
  65. argsList := make([]reflect.Value, argsLen)
  66. for i := 0; i < argsLen; i++ {
  67. argsList[i] = reflect.ValueOf(args[i])
  68. }
  69. method.Call(argsList)
  70. }
  71. //检测开关-在远程调用前是否进行合法检测
  72. var CheckServiceFuncMapBeforInvoke = false
  73. //为了防止非法远程调用,只能调用Map中记录的方法
  74. var ServiceFuncMap = make(map[string]bool)
  75. func invokeFuncByDataPack(obj interface{}, dp *dataPack) {
  76. if dp.Type == 1 {
  77. if !CheckServiceFuncMapBeforInvoke || ServiceFuncMap[dp.Func] {
  78. invokeFunc(obj, dp.Func, dp.Args...)
  79. }
  80. }
  81. }