Commit 0e5d52de758452c895c98fcab944663a9dc8f6bf
1 parent
7f269318
reactor: 重构底层框架1.0
Showing
46 changed files
with
830 additions
and
537 deletions
 
Show diff stats
Makefile
| ... | ... | @@ -7,12 +7,12 @@ gen: | 
| 7 | 7 | protoc-go-inject-tag -input=./pb/*.pb.go | 
| 8 | 8 | |
| 9 | 9 | test: | 
| 10 | - go run test/client.go | |
| 10 | + go run cmd/test/client.go | |
| 11 | 11 | http: | 
| 12 | - go run -race cmd/http.go | |
| 12 | + go run -race cmd/httpserver/*.go | |
| 13 | 13 | |
| 14 | 14 | game: | 
| 15 | - go run -race cmd/game.go | |
| 15 | + go run -race cmd/gameserver/*.go | |
| 16 | 16 | build: | 
| 17 | 17 | go build -race -o bin/account cmd/http.go | 
| 18 | 18 | go build -race -o bin/game cmd/game.go | ... | ... | 
cmd/game.go deleted
| ... | ... | @@ -1,41 +0,0 @@ | 
| 1 | -package main | |
| 2 | - | |
| 3 | -import ( | |
| 4 | - _ "net/http/pprof" | |
| 5 | - "os" | |
| 6 | - "os/signal" | |
| 7 | - "pro2d/conf" | |
| 8 | - "pro2d/src/components/logger" | |
| 9 | - "pro2d/src/components/net" | |
| 10 | - _ "pro2d/src/plugin" | |
| 11 | - "syscall" | |
| 12 | -) | |
| 13 | - | |
| 14 | -func main() { | |
| 15 | - err := make(chan error) | |
| 16 | - stopChan := make(chan os.Signal) | |
| 17 | - signal.Notify(stopChan, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL) | |
| 18 | - | |
| 19 | - userChan := make(chan os.Signal) | |
| 20 | - signal.Notify(userChan, syscall.SIGUSR1, syscall.SIGUSR2) | |
| 21 | - | |
| 22 | - s := net.NewServer(conf.GlobalConf.GameConf) | |
| 23 | - go func() { | |
| 24 | - err <- s.Start() | |
| 25 | - }() | |
| 26 | - | |
| 27 | - for { | |
| 28 | - select { | |
| 29 | - case e := <- err: | |
| 30 | - logger.Error("game server error: %v", e) | |
| 31 | - return | |
| 32 | - case <-stopChan: | |
| 33 | - s.Stop() | |
| 34 | - logger.Debug("game stop...") | |
| 35 | - return | |
| 36 | - case u := <-userChan: | |
| 37 | - logger.Debug("userChan .. %v",u.String()) | |
| 38 | - s.LoadPlugin() | |
| 39 | - } | |
| 40 | - } | |
| 41 | -} | 
| ... | ... | @@ -0,0 +1,132 @@ | 
| 1 | +package main | |
| 2 | + | |
| 3 | +import ( | |
| 4 | + "fmt" | |
| 5 | + "github.com/golang/protobuf/proto" | |
| 6 | + "math" | |
| 7 | + "pro2d/common" | |
| 8 | + "pro2d/common/components" | |
| 9 | + "pro2d/models" | |
| 10 | + "pro2d/pb" | |
| 11 | + "pro2d/utils" | |
| 12 | + "pro2d/utils/logger" | |
| 13 | + "sync/atomic" | |
| 14 | +) | |
| 15 | + | |
| 16 | +type Agent struct { | |
| 17 | + components.IConnection | |
| 18 | + Server components.IServer | |
| 19 | + | |
| 20 | + Role *models.RoleModel | |
| 21 | + | |
| 22 | + readFunc chan func() | |
| 23 | + timerFunc chan func() | |
| 24 | + Quit chan *Agent | |
| 25 | + | |
| 26 | + nextCheckTime int64 //下一次检查的时间 | |
| 27 | + lastHeartCheckTime int64 | |
| 28 | + heartTimeoutCount int //超时次数 | |
| 29 | +} | |
| 30 | + | |
| 31 | +func NewAgent(s components.IServer) *Agent { | |
| 32 | + return &Agent{ | |
| 33 | + Server: s, | |
| 34 | + readFunc: make(chan func(), 10), | |
| 35 | + timerFunc: make(chan func(), 10), | |
| 36 | + Quit: make(chan *Agent), | |
| 37 | + | |
| 38 | + nextCheckTime: 0, | |
| 39 | + lastHeartCheckTime: utils.Timex(), | |
| 40 | + heartTimeoutCount: 0, | |
| 41 | + } | |
| 42 | +} | |
| 43 | + | |
| 44 | +func (c *Agent) listen() { | |
| 45 | + defer c.Close() | |
| 46 | + for { | |
| 47 | + select { | |
| 48 | + case timerFunc := <- c.timerFunc: | |
| 49 | + timerFunc() | |
| 50 | + case readFunc := <- c.readFunc: | |
| 51 | + readFunc() | |
| 52 | + case <- c.Quit: | |
| 53 | + return | |
| 54 | + } | |
| 55 | + } | |
| 56 | +} | |
| 57 | + | |
| 58 | +func (c *Agent) OnConnection(conn components.IConnection) { | |
| 59 | + c.IConnection = conn | |
| 60 | + go c.listen() | |
| 61 | +} | |
| 62 | + | |
| 63 | +func (c *Agent) OnMessage(msg components.IMessage) { | |
| 64 | + f := func() { | |
| 65 | + atomic.StoreInt64(&c.lastHeartCheckTime, utils.Timex()) | |
| 66 | + if md, ok := components.ActionMap[pb.ProtoCode(msg.GetHeader().GetMsgID())]; ok { | |
| 67 | + logger.Debug("protocode handler: %d", msg.GetHeader().GetMsgID()) | |
| 68 | + errCode, protomsg := md(msg) | |
| 69 | + rsp, err := proto.Marshal(protomsg) | |
| 70 | + fmt.Printf("errCode: %d, protomsg:%v\n", errCode, protomsg) | |
| 71 | + if err != nil { | |
| 72 | + conn := c.Server.GetIConnection(msg.GetSessId()) | |
| 73 | + if conn != nil { | |
| 74 | + conn.Send(-100, msg.GetHeader().GetMsgID(), nil) | |
| 75 | + } | |
| 76 | + return | |
| 77 | + } | |
| 78 | + conn := c.Server.GetIConnection(msg.GetSessId()) | |
| 79 | + if conn != nil { | |
| 80 | + conn.Send(errCode, msg.GetHeader().GetMsgID(), rsp) | |
| 81 | + } | |
| 82 | + return | |
| 83 | + } | |
| 84 | + logger.Error("protocode not handler: %d", msg.GetHeader().GetMsgID()) | |
| 85 | + } | |
| 86 | + c.readFunc <- f | |
| 87 | +} | |
| 88 | + | |
| 89 | +func (c *Agent) OnClose() { | |
| 90 | + c.Quit <- c | |
| 91 | +} | |
| 92 | + | |
| 93 | +func (c *Agent) Close() { | |
| 94 | + if c.Role == nil { | |
| 95 | + return | |
| 96 | + } | |
| 97 | + | |
| 98 | + c.Role.OnOfflineEvent() | |
| 99 | +} | |
| 100 | + | |
| 101 | +func (c *Agent) checkHeartBeat(now int64) { | |
| 102 | + lastHeartCheckTime := atomic.LoadInt64(&c.lastHeartCheckTime) | |
| 103 | + logger.Debug("checkHeartBeat ID: %d, last: %d, now: %d", c.GetID(), lastHeartCheckTime, now) | |
| 104 | + if math.Abs(float64(lastHeartCheckTime - now)) > common.HeartTimerInterval { | |
| 105 | + c.heartTimeoutCount++ | |
| 106 | + if c.heartTimeoutCount >= common.HeartTimeoutCountMax { | |
| 107 | + c.Stop() | |
| 108 | + return | |
| 109 | + } | |
| 110 | + logger.Debug("timeout count: %d", c.heartTimeoutCount) | |
| 111 | + }else { | |
| 112 | + c.heartTimeoutCount = 0 | |
| 113 | + } | |
| 114 | +} | |
| 115 | + | |
| 116 | +func (c *Agent) update() { | |
| 117 | + nextCheckTime := atomic.LoadInt64(&c.nextCheckTime) | |
| 118 | + now := utils.Timex() | |
| 119 | + if now >= nextCheckTime { | |
| 120 | + //检查心跳 | |
| 121 | + c.checkHeartBeat(now) | |
| 122 | + nextCheckTime = now + common.HeartTimerInterval | |
| 123 | + atomic.StoreInt64(&c.nextCheckTime, nextCheckTime) | |
| 124 | + } | |
| 125 | + | |
| 126 | + c.timerFunc <- func() { | |
| 127 | + if c.Role != nil { | |
| 128 | + //role 恢复数据 | |
| 129 | + c.Role.OnRecoverTimer(now) | |
| 130 | + } | |
| 131 | + } | |
| 132 | +} | ... | ... | 
| ... | ... | @@ -0,0 +1,125 @@ | 
| 1 | +package main | |
| 2 | + | |
| 3 | +import ( | |
| 4 | + "context" | |
| 5 | + "fmt" | |
| 6 | + _ "net/http/pprof" | |
| 7 | + "os" | |
| 8 | + "os/signal" | |
| 9 | + "pro2d/common/components" | |
| 10 | + "pro2d/conf" | |
| 11 | + "pro2d/models" | |
| 12 | + _ "pro2d/plugin" | |
| 13 | + "pro2d/utils/db" | |
| 14 | + "pro2d/utils/etcd" | |
| 15 | + "pro2d/utils/logger" | |
| 16 | + "sync" | |
| 17 | + "syscall" | |
| 18 | + "time" | |
| 19 | +) | |
| 20 | + | |
| 21 | +type GameServer struct { | |
| 22 | + components.IServer | |
| 23 | + EtcdClient *etcd.EtcdClient | |
| 24 | + | |
| 25 | + Agents *sync.Map | |
| 26 | +} | |
| 27 | + | |
| 28 | +func NewGameServer(sconf *conf.SConf) (*GameServer, error) { | |
| 29 | + s := &GameServer{ | |
| 30 | + IServer: components.NewServer(sconf.Port, conf.GlobalConf.GameConf.PluginPath, components.NewPBSplitter()), | |
| 31 | + Agents: new(sync.Map), | |
| 32 | + } | |
| 33 | + s.SetConnectionCallback(s.OnConnection) | |
| 34 | + s.SetMessageCallback(s.OnMessage) | |
| 35 | + s.SetCloseCallback(s.OnClose) | |
| 36 | + | |
| 37 | + //mongo 初始化 | |
| 38 | + db.MongoDatabase = db.MongoClient.Database(sconf.DBName) | |
| 39 | + models.InitGameServerModels() | |
| 40 | + | |
| 41 | + //Etcd 初始化 | |
| 42 | + var err error | |
| 43 | + s.EtcdClient, err = etcd.NewEtcdClient(conf.GlobalConf.Etcd) | |
| 44 | + if err != nil { | |
| 45 | + return nil, err | |
| 46 | + } | |
| 47 | + s.EtcdClient.PutWithLeasePrefix(conf.GlobalConf.GameConf.Name, conf.GlobalConf.GameConf.ID, fmt.Sprintf("%s:%d", conf.GlobalConf.GameConf.IP, conf.GlobalConf.GameConf.Port), 5) | |
| 48 | + | |
| 49 | + go s.handleTimeOut() | |
| 50 | + return s, nil | |
| 51 | +} | |
| 52 | + | |
| 53 | +func (s *GameServer) OnConnection(conn components.IConnection) { | |
| 54 | + agent := NewAgent(s) | |
| 55 | + agent.OnConnection(conn) | |
| 56 | + s.Agents.Store(conn.GetID(),agent) | |
| 57 | +} | |
| 58 | + | |
| 59 | +func (s *GameServer) OnMessage(msg components.IMessage) { | |
| 60 | + agent, ok := s.Agents.Load(msg.GetSessId()) | |
| 61 | + if !ok { | |
| 62 | + return | |
| 63 | + } | |
| 64 | + agent.(*Agent).OnMessage(msg) | |
| 65 | +} | |
| 66 | + | |
| 67 | +func (s *GameServer) OnClose(conn components.IConnection) { | |
| 68 | + agent, ok := s.Agents.Load(conn.GetID()) | |
| 69 | + if !ok { | |
| 70 | + return | |
| 71 | + } | |
| 72 | + agent.(*Agent).OnClose() | |
| 73 | + s.Agents.Delete(conn.GetID()) | |
| 74 | +} | |
| 75 | + | |
| 76 | +func (s *GameServer) Stop() { | |
| 77 | + s.IServer.Stop() | |
| 78 | + | |
| 79 | + db.MongoClient.Disconnect(context.TODO()) | |
| 80 | +} | |
| 81 | + | |
| 82 | + | |
| 83 | +func (s *GameServer) handleTimeOut() { | |
| 84 | + s.Agents.Range(func(key, value interface{}) bool { | |
| 85 | + agent := value.(*Agent) | |
| 86 | + agent.update() | |
| 87 | + return true | |
| 88 | + }) | |
| 89 | + | |
| 90 | + components.TimeOut(1*time.Second, s.handleTimeOut) | |
| 91 | +} | |
| 92 | + | |
| 93 | +func main() { | |
| 94 | + err := make(chan error) | |
| 95 | + stopChan := make(chan os.Signal) | |
| 96 | + signal.Notify(stopChan, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL) | |
| 97 | + | |
| 98 | + userChan := make(chan os.Signal) | |
| 99 | + signal.Notify(userChan, syscall.SIGUSR1, syscall.SIGUSR2) | |
| 100 | + | |
| 101 | + s,err1 := NewGameServer(conf.GlobalConf.GameConf) | |
| 102 | + if err1 != nil { | |
| 103 | + fmt.Errorf(err1.Error()) | |
| 104 | + return | |
| 105 | + } | |
| 106 | + | |
| 107 | + go func() { | |
| 108 | + err <- s.Start() | |
| 109 | + }() | |
| 110 | + | |
| 111 | + for { | |
| 112 | + select { | |
| 113 | + case e := <- err: | |
| 114 | + logger.Error("game server error: %v", e) | |
| 115 | + return | |
| 116 | + case <-stopChan: | |
| 117 | + s.Stop() | |
| 118 | + logger.Debug("game stop...") | |
| 119 | + return | |
| 120 | + case u := <-userChan: | |
| 121 | + logger.Debug("userChan .. %v",u.String()) | |
| 122 | + //s.LoadPlugin() | |
| 123 | + } | |
| 124 | + } | |
| 125 | +} | ... | ... | 
src/actions/AccountAction.go renamed to cmd/httpserver/AccountAction.go
| 1 | -package actions | |
| 1 | +package main | |
| 2 | 2 | |
| 3 | 3 | import ( | 
| 4 | 4 | "github.com/gin-gonic/gin" | 
| 5 | 5 | "pro2d/conf" | 
| 6 | + "pro2d/models" | |
| 6 | 7 | "pro2d/pb" | 
| 7 | - "pro2d/src/components/net" | |
| 8 | - "pro2d/src/models" | |
| 9 | - "pro2d/src/utils" | |
| 8 | + "pro2d/utils" | |
| 10 | 9 | ) | 
| 11 | 10 | |
| 12 | 11 | type AccountAction struct { | 
| 13 | - HttpServer *net.HttpServer | |
| 12 | + HttpServer *AccountServer | |
| 14 | 13 | } | 
| 15 | 14 | |
| 16 | 15 | func (h *AccountAction) Register(c *gin.Context) (int, interface{}){ | ... | ... | 
cmd/http.go renamed to cmd/httpserver/http.go
| 1 | 1 | package main | 
| 2 | 2 | |
| 3 | 3 | import ( | 
| 4 | + "fmt" | |
| 4 | 5 | "os" | 
| 5 | 6 | "os/signal" | 
| 7 | + "pro2d/common/components" | |
| 8 | + "pro2d/conf" | |
| 6 | 9 | _ "pro2d/conf" | 
| 7 | - "pro2d/src/actions" | |
| 8 | - "pro2d/src/components/logger" | |
| 9 | - "pro2d/src/components/net" | |
| 10 | + "pro2d/models" | |
| 11 | + "pro2d/utils/db" | |
| 12 | + "pro2d/utils/etcd" | |
| 13 | + "pro2d/utils/logger" | |
| 10 | 14 | "syscall" | 
| 11 | 15 | ) | 
| 12 | 16 | |
| 17 | +type AccountServer struct { | |
| 18 | + components.IHttp | |
| 19 | + EtcdClient *etcd.EtcdClient | |
| 20 | +} | |
| 21 | + | |
| 22 | +func NewAccountServer(version string, port ...string) *AccountServer { | |
| 23 | + return &AccountServer{IHttp: components.NewHttpServer(version, port...)} | |
| 24 | +} | |
| 25 | + | |
| 26 | +func (s *AccountServer) Start() error { | |
| 27 | + //mongo 初始化 | |
| 28 | + db.MongoDatabase = db.MongoClient.Database(conf.GlobalConf.AccountConf.DBName) | |
| 29 | + models.InitAccountServerModels() | |
| 30 | + | |
| 31 | + //Etcd 初始化 | |
| 32 | + var err error | |
| 33 | + s.EtcdClient, err = etcd.NewEtcdClient(conf.GlobalConf.Etcd) | |
| 34 | + if err != nil { | |
| 35 | + return err | |
| 36 | + } | |
| 37 | + s.EtcdClient.PutWithLeasePrefix(conf.GlobalConf.AccountConf.Name, conf.GlobalConf.AccountConf.ID, fmt.Sprintf("%s:%d", conf.GlobalConf.AccountConf.IP, conf.GlobalConf.AccountConf.Port), 5) | |
| 38 | + return nil | |
| 39 | +} | |
| 40 | + | |
| 13 | 41 | func main() { | 
| 14 | 42 | err := make(chan error) | 
| 15 | 43 | stopChan := make(chan os.Signal) | 
| 16 | 44 | signal.Notify(stopChan, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL) | 
| 17 | 45 | |
| 18 | - web := net.NewHttpServer("v1") | |
| 19 | - web.BindHandler(&actions.AccountAction{HttpServer: web}) | |
| 46 | + web := NewAccountServer("v1") | |
| 47 | + web.BindHandler(&AccountAction{HttpServer: web}) | |
| 20 | 48 | go func() { | 
| 21 | 49 | err <- web.Start() | 
| 22 | 50 | }() | 
| ... | ... | @@ -26,5 +54,6 @@ func main() { | 
| 26 | 54 | logger.Error("game server error: %v", e) | 
| 27 | 55 | case <-stopChan: | 
| 28 | 56 | logger.Debug("game stop") | 
| 57 | + web.Stop() | |
| 29 | 58 | } | 
| 30 | 59 | } | 
| 31 | 60 | \ No newline at end of file | ... | ... | 
src/components/net/http_test.go renamed to cmd/httpserver/http_test.go
| 1 | -package net | |
| 1 | +package main | |
| 2 | 2 | |
| 3 | 3 | import ( | 
| 4 | 4 | "github.com/gin-gonic/gin" | 
| 5 | + "pro2d/common/components" | |
| 5 | 6 | "testing" | 
| 6 | 7 | ) | 
| 7 | 8 | |
| ... | ... | @@ -16,7 +17,7 @@ func (h *HttpAction) PrintB(c *gin.Context) (int, interface{}) { | 
| 16 | 17 | } | 
| 17 | 18 | |
| 18 | 19 | func TestHttpServer_Start(t *testing.T) { | 
| 19 | - web := NewHttpServer("v1") | |
| 20 | + web := components.NewHttpServer("v1") | |
| 20 | 21 | web.BindHandler(&HttpAction{}) | 
| 21 | 22 | web.Start() | 
| 22 | 23 | } | 
| 23 | 24 | \ No newline at end of file | ... | ... | 
test/client.go renamed to cmd/test/client.go
| ... | ... | @@ -6,17 +6,17 @@ import ( | 
| 6 | 6 | "encoding/binary" | 
| 7 | 7 | "github.com/golang/protobuf/proto" | 
| 8 | 8 | "net" | 
| 9 | + "pro2d/common/components" | |
| 9 | 10 | "pro2d/pb" | 
| 10 | - "pro2d/src/components/logger" | |
| 11 | - net2 "pro2d/src/components/net" | |
| 11 | + "pro2d/utils/logger" | |
| 12 | 12 | "time" | 
| 13 | 13 | ) | 
| 14 | 14 | |
| 15 | 15 | func main() { | 
| 16 | 16 | |
| 17 | - head := &net2.Head{ | |
| 17 | + head := &components.PBHead{ | |
| 18 | 18 | Length: 0, | 
| 19 | - Cmd: int32(pb.ProtoCode_LoginReq), | |
| 19 | + Cmd: uint32(pb.ProtoCode_LoginReq), | |
| 20 | 20 | ErrCode: 0, | 
| 21 | 21 | PreField: 0, | 
| 22 | 22 | } | 
| ... | ... | @@ -27,11 +27,11 @@ func main() { | 
| 27 | 27 | } | 
| 28 | 28 | l, _ :=proto.Marshal(loginReq) | 
| 29 | 29 | |
| 30 | - b := net2.MsgPkg{ | |
| 30 | + b := components.PBMessage{ | |
| 31 | 31 | Head: head, | 
| 32 | 32 | Body: l, | 
| 33 | 33 | } | 
| 34 | - head.Length = int32(16 + len(b.Body)) | |
| 34 | + head.Length = uint32(16 + len(b.Body)) | |
| 35 | 35 | buf := &bytes.Buffer{} | 
| 36 | 36 | err := binary.Write(buf, binary.BigEndian, head) | 
| 37 | 37 | if err != nil { | 
| ... | ... | @@ -46,7 +46,7 @@ func main() { | 
| 46 | 46 | return | 
| 47 | 47 | } | 
| 48 | 48 | |
| 49 | - client, err := net.Dial("tcp", "localhost:8849") | |
| 49 | + client, err := net.Dial("tcp", "localhost:8850") | |
| 50 | 50 | if err != nil { | 
| 51 | 51 | logger.Error(err) | 
| 52 | 52 | return | ... | ... | 
test/client_test.go renamed to cmd/test/client_test.go
| ... | ... | @@ -0,0 +1,122 @@ | 
| 1 | +package components | |
| 2 | + | |
| 3 | +import ( | |
| 4 | + "bufio" | |
| 5 | + "errors" | |
| 6 | + "net" | |
| 7 | + "pro2d/common" | |
| 8 | + "pro2d/utils/logger" | |
| 9 | + "time" | |
| 10 | +) | |
| 11 | + | |
| 12 | + | |
| 13 | +type Connection struct { | |
| 14 | + IConnection | |
| 15 | + net.Conn | |
| 16 | + Server IServer | |
| 17 | + Id int | |
| 18 | + | |
| 19 | + scanner *bufio.Scanner | |
| 20 | + writer *bufio.Writer | |
| 21 | + WBuffer chan []byte | |
| 22 | + Quit chan *Connection | |
| 23 | + | |
| 24 | + messageCallback MessageCallback | |
| 25 | + connectionCallback ConnectionCallback | |
| 26 | + closeCallback CloseCallback | |
| 27 | + timerCallback TimerCallback | |
| 28 | +} | |
| 29 | + | |
| 30 | +func NewConn(id int, conn net.Conn, s IServer) *Connection { | |
| 31 | + return &Connection{ | |
| 32 | + Id: id, | |
| 33 | + Conn: conn, | |
| 34 | + Server: s, | |
| 35 | + | |
| 36 | + scanner: bufio.NewScanner(conn), | |
| 37 | + writer: bufio.NewWriter(conn), | |
| 38 | + WBuffer: make(chan []byte, common.MaxMsgChan), | |
| 39 | + Quit: make(chan *Connection), | |
| 40 | + } | |
| 41 | +} | |
| 42 | + | |
| 43 | +func (c *Connection) GetID() int { | |
| 44 | + return c.Id | |
| 45 | +} | |
| 46 | + | |
| 47 | +func (c *Connection) SetConnectionCallback(cb ConnectionCallback) { | |
| 48 | + c.connectionCallback = cb | |
| 49 | +} | |
| 50 | + | |
| 51 | +func (c *Connection) SetMessageCallback(cb MessageCallback) { | |
| 52 | + c.messageCallback = cb | |
| 53 | +} | |
| 54 | + | |
| 55 | +func (c *Connection) SetCloseCallback(cb CloseCallback) { | |
| 56 | + c.closeCallback = cb | |
| 57 | +} | |
| 58 | + | |
| 59 | +func (c *Connection) write() { | |
| 60 | + defer c.Stop() | |
| 61 | + | |
| 62 | + for msg := range c.WBuffer { | |
| 63 | + n, err := c.writer.Write(msg) | |
| 64 | + if err != nil{ | |
| 65 | + logger.Error("write fail err: " + err.Error(), "n: ", n) | |
| 66 | + return | |
| 67 | + } | |
| 68 | + if err := c.writer.Flush(); err != nil { | |
| 69 | + logger.Error("write Flush fail err: " + err.Error()) | |
| 70 | + return | |
| 71 | + } | |
| 72 | + } | |
| 73 | +} | |
| 74 | + | |
| 75 | +func (c *Connection) read() { | |
| 76 | + defer c.Stop() | |
| 77 | + c.scanner.Split(c.Server.GetSplitter().ParseMsg) | |
| 78 | + | |
| 79 | + for c.scanner.Scan() { | |
| 80 | + req, err := c.Server.GetSplitter().UnPack(c.scanner.Bytes()) | |
| 81 | + if err != nil { | |
| 82 | + return | |
| 83 | + } | |
| 84 | + | |
| 85 | + req.SetSessId(c.Id) | |
| 86 | + c.messageCallback(req) | |
| 87 | + } | |
| 88 | + | |
| 89 | + if err := c.scanner.Err(); err != nil { | |
| 90 | + logger.Error("scanner.err: %s", err.Error()) | |
| 91 | + return | |
| 92 | + } | |
| 93 | +} | |
| 94 | + | |
| 95 | +func (c *Connection) Start() { | |
| 96 | + c.connectionCallback(c) | |
| 97 | + go c.write() | |
| 98 | + go c.read() | |
| 99 | +} | |
| 100 | + | |
| 101 | +func (c *Connection) Stop() { | |
| 102 | + logger.Debug("ID: %d close", c.Id) | |
| 103 | + c.Conn.Close() | |
| 104 | + c.closeCallback(c) | |
| 105 | +} | |
| 106 | + | |
| 107 | +func (c *Connection) Send(errCode int32, cmd uint32, data []byte) error{ | |
| 108 | + buf, err := c.Server.GetSplitter().Pack(cmd, data, errCode, 0) | |
| 109 | + if err != nil { | |
| 110 | + return err | |
| 111 | + } | |
| 112 | + | |
| 113 | + sendTimeout := time.NewTimer(5 * time.Millisecond) | |
| 114 | + defer sendTimeout.Stop() | |
| 115 | + // 发送超时 | |
| 116 | + select { | |
| 117 | + case <-sendTimeout.C: | |
| 118 | + return errors.New("send buff msg timeout") | |
| 119 | + case c.WBuffer <- buf: | |
| 120 | + return nil | |
| 121 | + } | |
| 122 | +} | ... | ... | 
src/components/net/http.go renamed to common/components/http.go
| 1 | -package net | |
| 1 | +package components | |
| 2 | 2 | |
| 3 | 3 | import ( | 
| 4 | - "fmt" | |
| 5 | 4 | "github.com/gin-gonic/gin" | 
| 6 | 5 | "net/http" | 
| 7 | - "pro2d/conf" | |
| 8 | - "pro2d/src/components/db" | |
| 9 | - "pro2d/src/components/etcd" | |
| 10 | - "pro2d/src/models" | |
| 11 | 6 | "reflect" | 
| 12 | 7 | "strings" | 
| 13 | 8 | ) | 
| 14 | 9 | |
| 15 | 10 | type HttpServer struct { | 
| 11 | + IHttp | |
| 16 | 12 | version string | 
| 17 | 13 | port []string | 
| 18 | - EtcdClient *etcd.EtcdClient | |
| 19 | - | |
| 20 | 14 | Handler interface{} | 
| 21 | 15 | } | 
| 22 | 16 | |
| ... | ... | @@ -30,6 +24,10 @@ func NewHttpServer(version string, port ...string) *HttpServer { | 
| 30 | 24 | return &HttpServer{version: version, port: port} | 
| 31 | 25 | } | 
| 32 | 26 | |
| 27 | +func GetRoutePath(objName, objFunc string) string { | |
| 28 | + return strings.ToLower(objName + "/" + objFunc) | |
| 29 | +} | |
| 30 | + | |
| 33 | 31 | func (h *HttpServer)HandlerFuncObj(tvl, obj reflect.Value) gin.HandlerFunc { | 
| 34 | 32 | return func(c *gin.Context) { | 
| 35 | 33 | v := tvl.Call([]reflect.Value{obj, reflect.ValueOf(c)}) | 
| ... | ... | @@ -41,27 +39,11 @@ func (h *HttpServer)HandlerFuncObj(tvl, obj reflect.Value) gin.HandlerFunc { | 
| 41 | 39 | } | 
| 42 | 40 | } | 
| 43 | 41 | |
| 44 | -func GetRoutePath(objName, objFunc string) string { | |
| 45 | - return strings.ToLower(objName + "/" + objFunc) | |
| 46 | -} | |
| 47 | - | |
| 48 | 42 | func (h *HttpServer) BindHandler(handler interface{}) { | 
| 49 | 43 | h.Handler = handler | 
| 50 | 44 | } | 
| 51 | 45 | |
| 52 | 46 | func (h *HttpServer) Start() error { | 
| 53 | - //mongo 初始化 | |
| 54 | - db.MongoDatabase = db.MongoClient.Database(conf.GlobalConf.AccountConf.DBName) | |
| 55 | - models.InitAccountServerModels() | |
| 56 | - | |
| 57 | - //Etcd 初始化 | |
| 58 | - var err error | |
| 59 | - h.EtcdClient, err = etcd.NewEtcdClient(conf.GlobalConf.Etcd) | |
| 60 | - if err != nil { | |
| 61 | - return err | |
| 62 | - } | |
| 63 | - h.EtcdClient.PutWithLeasePrefix(conf.GlobalConf.AccountConf.Name, conf.GlobalConf.AccountConf.ID, fmt.Sprintf("%s:%d", conf.GlobalConf.AccountConf.IP, conf.GlobalConf.AccountConf.Port), 5) | |
| 64 | - | |
| 65 | 47 | //gin初始化 | 
| 66 | 48 | r := gin.Default() | 
| 67 | 49 | r.GET("/ping", Pong) | ... | ... | 
| ... | ... | @@ -0,0 +1,68 @@ | 
| 1 | +package components | |
| 2 | + | |
| 3 | +//网络包头 | |
| 4 | +type IHead interface { | |
| 5 | + GetDataLen() uint32 //获取消息数据段长度 | |
| 6 | + GetMsgID() uint32 //获取消息ID | |
| 7 | + GetErrCode() int32 //获取消息错误码 | |
| 8 | + GetPreserve() uint32 //获取预留数据 | |
| 9 | +} | |
| 10 | + | |
| 11 | +//网络包 | |
| 12 | +type IMessage interface { | |
| 13 | + IHead | |
| 14 | + GetHeader() IHead //获取消息头 | |
| 15 | + SetHeader(header IHead) //设置消息头 | |
| 16 | + | |
| 17 | + GetData() []byte //获取消息内容 | |
| 18 | + SetData([]byte) //设置消息内容 | |
| 19 | + | |
| 20 | + SetSessId(int) //设置连接id | |
| 21 | + GetSessId() int //获取连接id | |
| 22 | +} | |
| 23 | + | |
| 24 | +//网络拆包解包器 | |
| 25 | +type ISplitter interface { | |
| 26 | + UnPack([]byte) (IMessage, error) | |
| 27 | + Pack(cmd uint32, data []byte, errcode int32, preserve uint32) ([]byte, error) | |
| 28 | + ParseMsg (data []byte, atEOF bool) (advance int, token []byte, err error) | |
| 29 | + GetHeadLen() uint32 | |
| 30 | +} | |
| 31 | + | |
| 32 | +//链接 | |
| 33 | +type IConnection interface { | |
| 34 | + GetID() int | |
| 35 | + Start() | |
| 36 | + Stop() | |
| 37 | + Send(code int32, cmd uint32, b []byte) error | |
| 38 | + | |
| 39 | + SetConnectionCallback(ConnectionCallback) | |
| 40 | + SetMessageCallback(MessageCallback) | |
| 41 | + SetCloseCallback(CloseCallback) | |
| 42 | +} | |
| 43 | + | |
| 44 | +type ConnectionCallback func(IConnection) | |
| 45 | +type CloseCallback func(IConnection) | |
| 46 | +type MessageCallback func(IMessage) | |
| 47 | +type TimerCallback func(IConnection) | |
| 48 | + | |
| 49 | +//server | |
| 50 | +type IServer interface { | |
| 51 | + Start() error | |
| 52 | + Stop() | |
| 53 | + | |
| 54 | + GetSplitter() ISplitter | |
| 55 | + GetIConnection(id int) IConnection | |
| 56 | + | |
| 57 | + SetConnectionCallback(ConnectionCallback) | |
| 58 | + SetMessageCallback(MessageCallback) | |
| 59 | + SetCloseCallback(CloseCallback) | |
| 60 | + SetTimerCallback(TimerCallback) | |
| 61 | +} | |
| 62 | + | |
| 63 | +//httpserver | |
| 64 | +type IHttp interface { | |
| 65 | + Start() error | |
| 66 | + Stop() | |
| 67 | + BindHandler(interface{}) | |
| 68 | +} | |
| 0 | 69 | \ No newline at end of file | ... | ... | 
| ... | ... | @@ -0,0 +1,134 @@ | 
| 1 | +package components | |
| 2 | + | |
| 3 | +import ( | |
| 4 | + "bytes" | |
| 5 | + "encoding/binary" | |
| 6 | + "fmt" | |
| 7 | + "pro2d/common" | |
| 8 | +) | |
| 9 | + | |
| 10 | +type PBHead struct { | |
| 11 | + Length uint32 | |
| 12 | + Cmd uint32 | |
| 13 | + ErrCode int32 | |
| 14 | + PreField uint32 | |
| 15 | +} | |
| 16 | + | |
| 17 | +func (h *PBHead) GetDataLen() uint32 { | |
| 18 | + return h.Length | |
| 19 | +} | |
| 20 | + | |
| 21 | +func (h *PBHead) GetMsgID() uint32 { | |
| 22 | + return h.Cmd | |
| 23 | +} | |
| 24 | + | |
| 25 | +func (h *PBHead) GetErrCode() int32 { | |
| 26 | + return h.ErrCode | |
| 27 | +} | |
| 28 | + | |
| 29 | +func (h *PBHead) GetPreserve() uint32 { | |
| 30 | + return h.PreField | |
| 31 | +} | |
| 32 | + | |
| 33 | +type PBMessage struct { | |
| 34 | + IMessage | |
| 35 | + Head IHead | |
| 36 | + Body []byte | |
| 37 | + | |
| 38 | + SessionID int | |
| 39 | +} | |
| 40 | + | |
| 41 | + | |
| 42 | +func (m *PBMessage) GetHeader() IHead { | |
| 43 | + return m.Head | |
| 44 | +} | |
| 45 | + | |
| 46 | +func (m *PBMessage) SetHeader(header IHead) { | |
| 47 | + m.Head = header | |
| 48 | +} | |
| 49 | +func (m *PBMessage) GetData() []byte { | |
| 50 | + return m.Body | |
| 51 | +} | |
| 52 | + | |
| 53 | +func (m *PBMessage) SetData(b []byte) { | |
| 54 | + m.Body = b | |
| 55 | +} | |
| 56 | + | |
| 57 | +func (m *PBMessage) SetSessId(id int) { | |
| 58 | + m.SessionID = id | |
| 59 | +} | |
| 60 | + | |
| 61 | +func (m *PBMessage) GetSessId() int { | |
| 62 | + return m.SessionID | |
| 63 | +} | |
| 64 | + | |
| 65 | + | |
| 66 | +type PBSplitter struct {} | |
| 67 | + | |
| 68 | +func NewPBSplitter() *PBSplitter { | |
| 69 | + return &PBSplitter{} | |
| 70 | +} | |
| 71 | + | |
| 72 | +func (m *PBSplitter) GetHeadLen() uint32 { | |
| 73 | + return uint32(binary.Size(PBHead{})) | |
| 74 | +} | |
| 75 | + | |
| 76 | +func (m *PBSplitter) UnPack(data []byte) (IMessage,error) { | |
| 77 | + h := &PBHead{} | |
| 78 | + err := binary.Read(bytes.NewReader(data), binary.BigEndian, h) | |
| 79 | + if err != nil { | |
| 80 | + return nil, err | |
| 81 | + } | |
| 82 | + | |
| 83 | + return &PBMessage{ | |
| 84 | + Head: h, | |
| 85 | + Body: data[m.GetHeadLen():], | |
| 86 | + },nil | |
| 87 | +} | |
| 88 | + | |
| 89 | +func (m *PBSplitter) ParseMsg (data []byte, atEOF bool) (advance int, token []byte, err error) { | |
| 90 | + // 表示我们已经扫描到结尾了 | |
| 91 | + if atEOF && len(data) == 0 { | |
| 92 | + return 0, nil, nil | |
| 93 | + } | |
| 94 | + if !atEOF && len(data) >= int(m.GetHeadLen()) { //4字节数据包长度 4字节指令 | |
| 95 | + length := int32(0) | |
| 96 | + binary.Read(bytes.NewReader(data[0:4]), binary.BigEndian, &length) | |
| 97 | + if length <= 0 { | |
| 98 | + return 0, nil, fmt.Errorf("length is 0") | |
| 99 | + } | |
| 100 | + | |
| 101 | + if length > common.MaxPacketLength { | |
| 102 | + return 0, nil, fmt.Errorf("length exceeds maximum length") | |
| 103 | + } | |
| 104 | + if int(length) <= len(data) { | |
| 105 | + return int(length) , data[:int(length)], nil | |
| 106 | + } | |
| 107 | + return 0 , nil, nil | |
| 108 | + } | |
| 109 | + if atEOF { | |
| 110 | + return len(data), data, nil | |
| 111 | + } | |
| 112 | + return 0, nil, nil | |
| 113 | +} | |
| 114 | + | |
| 115 | +func (m *PBSplitter) Pack(cmd uint32, data []byte, errcode int32, preserve uint32) ([]byte, error) { | |
| 116 | + buf := &bytes.Buffer{} | |
| 117 | + h := &PBHead{ | |
| 118 | + Length: m.GetHeadLen()+ uint32(len(data)), | |
| 119 | + Cmd: cmd, | |
| 120 | + ErrCode: errcode, | |
| 121 | + PreField: preserve, | |
| 122 | + } | |
| 123 | + err := binary.Write(buf, binary.BigEndian, h) | |
| 124 | + if err != nil { | |
| 125 | + return nil, err | |
| 126 | + } | |
| 127 | + | |
| 128 | + err = binary.Write(buf, binary.BigEndian, data) | |
| 129 | + if err != nil { | |
| 130 | + return nil, err | |
| 131 | + } | |
| 132 | + | |
| 133 | + return buf.Bytes(), nil | |
| 134 | +} | |
| 0 | 135 | \ No newline at end of file | ... | ... | 
| ... | ... | @@ -0,0 +1,126 @@ | 
| 1 | +package components | |
| 2 | + | |
| 3 | +import ( | |
| 4 | + "fmt" | |
| 5 | + "github.com/golang/protobuf/proto" | |
| 6 | + "net" | |
| 7 | + "plugin" | |
| 8 | + "pro2d/pb" | |
| 9 | + "pro2d/utils/logger" | |
| 10 | + "sync" | |
| 11 | +) | |
| 12 | + | |
| 13 | +type ActionHandler func (msg IMessage) (int32, proto.Message) | |
| 14 | +var ActionMap map[pb.ProtoCode]ActionHandler | |
| 15 | + | |
| 16 | +type Server struct { | |
| 17 | + IServer | |
| 18 | + | |
| 19 | + connectionCallback ConnectionCallback | |
| 20 | + messageCallback MessageCallback | |
| 21 | + closeCallback CloseCallback | |
| 22 | + | |
| 23 | + splitter ISplitter | |
| 24 | + | |
| 25 | + port int | |
| 26 | + PluginPath string | |
| 27 | + Clients *sync.Map | |
| 28 | +} | |
| 29 | + | |
| 30 | +func NewServer(port int, pluginPath string, splitter ISplitter) *Server { | |
| 31 | + s := &Server{ | |
| 32 | + splitter: splitter, | |
| 33 | + port: port, | |
| 34 | + PluginPath: pluginPath, | |
| 35 | + Clients: new(sync.Map), | |
| 36 | + } | |
| 37 | + return s | |
| 38 | +} | |
| 39 | + | |
| 40 | +func (s *Server) GetSplitter() ISplitter { | |
| 41 | + return s.splitter | |
| 42 | +} | |
| 43 | + | |
| 44 | +func (s *Server) GetIConnection(id int) IConnection { | |
| 45 | + c, ok := s.Clients.Load(id) | |
| 46 | + if !ok { | |
| 47 | + return nil | |
| 48 | + } | |
| 49 | + return c.(IConnection) | |
| 50 | +} | |
| 51 | + | |
| 52 | +func (s *Server) SetConnectionCallback(cb ConnectionCallback) { | |
| 53 | + s.connectionCallback = cb | |
| 54 | +} | |
| 55 | + | |
| 56 | +func (s *Server) SetMessageCallback(cb MessageCallback) { | |
| 57 | + s.messageCallback = cb | |
| 58 | +} | |
| 59 | + | |
| 60 | +func (s *Server) SetCloseCallback(cb CloseCallback) { | |
| 61 | + s.closeCallback = cb | |
| 62 | +} | |
| 63 | + | |
| 64 | +func (s *Server) SetTimerCallback(cb TimerCallback) { | |
| 65 | +} | |
| 66 | + | |
| 67 | +func (s *Server) newConnection(conn IConnection) { | |
| 68 | + s.Clients.Store(conn.GetID(), conn) | |
| 69 | + | |
| 70 | + conn.SetConnectionCallback(s.connectionCallback) | |
| 71 | + conn.SetCloseCallback(s.removeConnection) | |
| 72 | + conn.SetMessageCallback(s.messageCallback) | |
| 73 | + | |
| 74 | + go conn.Start() | |
| 75 | +} | |
| 76 | + | |
| 77 | +func (s *Server) removeConnection(conn IConnection) { | |
| 78 | + s.closeCallback(conn) | |
| 79 | + s.Clients.Delete(conn.GetID()) | |
| 80 | +} | |
| 81 | + | |
| 82 | +func (s *Server) LoadPlugin() { | |
| 83 | + //重新加载 | |
| 84 | + _, err:=plugin.Open(s.PluginPath) | |
| 85 | + if err != nil { | |
| 86 | + logger.Error("load plugin err: %v, %s", err, s.PluginPath) | |
| 87 | + return | |
| 88 | + } | |
| 89 | + logger.Debug("load plugin success") | |
| 90 | +} | |
| 91 | + | |
| 92 | + | |
| 93 | +func (s *Server) Start() error { | |
| 94 | + //初始化plugin | |
| 95 | + //_, err = plugin.Open(conf.GlobalConf.GameConf.PluginPath) | |
| 96 | + //if err != nil { | |
| 97 | + // return err | |
| 98 | + //} | |
| 99 | + port := fmt.Sprintf(":%d", s.port) | |
| 100 | + l, err := net.Listen("tcp", port) | |
| 101 | + if err != nil { | |
| 102 | + return err | |
| 103 | + } | |
| 104 | + //监听端口 | |
| 105 | + logger.Debug("listen on %s\n", port) | |
| 106 | + id := 0 | |
| 107 | + for { | |
| 108 | + conn, err := l.Accept() | |
| 109 | + if err != nil { | |
| 110 | + return err | |
| 111 | + } | |
| 112 | + | |
| 113 | + id++ | |
| 114 | + client := NewConn(id, conn, s) | |
| 115 | + s.newConnection(client) | |
| 116 | + } | |
| 117 | +} | |
| 118 | + | |
| 119 | +func (s *Server)Stop() { | |
| 120 | + StopTimer() | |
| 121 | + s.Clients.Range(func(key, value interface{}) bool { | |
| 122 | + client := value.(IConnection) | |
| 123 | + client.Stop() | |
| 124 | + return true | |
| 125 | + }) | |
| 126 | +} | ... | ... | 
src/components/timewheel/timerwheel.go renamed to common/components/timerwheel.go
| 1 | -package timewheel | |
| 1 | +package components | |
| 2 | 2 | |
| 3 | 3 | import ( | 
| 4 | 4 | "container/list" | 
| 5 | - "pro2d/src/common" | |
| 6 | - "pro2d/src/components/workpool" | |
| 5 | + "pro2d/common" | |
| 7 | 6 | "sync" | 
| 8 | 7 | "sync/atomic" | 
| 9 | 8 | "time" | 
| ... | ... | @@ -73,16 +72,16 @@ type TimeWheel struct { | 
| 73 | 72 | t [4][TimeLevel]*bucket | 
| 74 | 73 | time uint32 | 
| 75 | 74 | |
| 76 | - WorkPool *workpool.WorkPool | |
| 75 | + WorkPool *WorkPool | |
| 77 | 76 | exit chan struct{} | 
| 78 | 77 | } | 
| 79 | 78 | |
| 80 | 79 | func NewTimeWheel() *TimeWheel { | 
| 81 | 80 | tw := &TimeWheel{ | 
| 82 | - tick: 10*time.Millisecond, | |
| 83 | - time: 0, | |
| 84 | - WorkPool: workpool.NewWorkPool(common.WorkerPoolSize, common.MaxTaskPerWorker), | |
| 85 | - exit: make(chan struct{}), | |
| 81 | + tick: 10*time.Millisecond, | |
| 82 | + time: 0, | |
| 83 | + WorkPool: NewWorkPool(common.WorkerPoolSize, common.MaxTaskPerWorker), | |
| 84 | + exit: make(chan struct{}), | |
| 86 | 85 | } | 
| 87 | 86 | for i :=0; i < TimeNear; i++ { | 
| 88 | 87 | tw.near[i] = newBucket() | ... | ... | 
src/components/timewheel/timewheel_test.go renamed to common/components/timewheel_test.go
src/components/workpool/workpool.go renamed to common/components/workpool.go
src/common/common.go renamed to common/const.go
| ... | ... | @@ -5,8 +5,9 @@ const ( | 
| 5 | 5 | WorkerPoolSize = 10 | 
| 6 | 6 | MaxTaskPerWorker = 100 | 
| 7 | 7 | |
| 8 | - //包头 | |
| 9 | - HEADLEN = 16 | |
| 8 | + //最大包大 | |
| 9 | + MaxPacketLength = 10 * 1024 * 1024 | |
| 10 | + MaxMsgChan = 100 | |
| 10 | 11 | |
| 11 | 12 | //jwt | 
| 12 | 13 | Pro2DTokenSignedString = "Pro2DSecret" | 
| ... | ... | @@ -19,6 +20,6 @@ const ( | 
| 19 | 20 | HeartTimerInterval = 5 //s | 
| 20 | 21 | HeartTimeoutCountMax = 20 //最大超时次数 | 
| 21 | 22 | |
| 22 | - //保存数据时间剑客 | |
| 23 | + //保存数据时间 | |
| 23 | 24 | SaveDataInterval = 5 //s | 
| 24 | 25 | ) | ... | ... | 
conf/conf.go
conf/conf.yaml
src/models/account.go renamed to models/account.go
| ... | ... | @@ -2,7 +2,7 @@ package models | 
| 2 | 2 | |
| 3 | 3 | import ( | 
| 4 | 4 | "pro2d/pb" | 
| 5 | - "pro2d/src/components/db" | |
| 5 | + "pro2d/utils/db" | |
| 6 | 6 | ) | 
| 7 | 7 | |
| 8 | 8 | type AccountModel struct { | 
| ... | ... | @@ -23,7 +23,7 @@ func NewAccount(phone string) *AccountModel { | 
| 23 | 23 | Phone: phone, | 
| 24 | 24 | } | 
| 25 | 25 | account := &AccountModel{ | 
| 26 | - Schema: db.NewSchema(phone, ac), | |
| 26 | + Schema: db.NewSchema(phone, ac), | |
| 27 | 27 | Account: ac, | 
| 28 | 28 | } | 
| 29 | 29 | ... | ... | 
src/models/equip.go renamed to models/equip.go
| ... | ... | @@ -2,7 +2,7 @@ package models | 
| 2 | 2 | |
| 3 | 3 | import ( | 
| 4 | 4 | "pro2d/pb" | 
| 5 | - "pro2d/src/components/db" | |
| 5 | + "pro2d/utils/db" | |
| 6 | 6 | ) | 
| 7 | 7 | |
| 8 | 8 | type EquipModels struct { | 
| ... | ... | @@ -16,7 +16,7 @@ func NewEquip(id string) *EquipModels { | 
| 16 | 16 | } | 
| 17 | 17 | m := &EquipModels{ | 
| 18 | 18 | Schema: db.NewSchema(id, data), | 
| 19 | - Equip: data, | |
| 19 | + Equip: data, | |
| 20 | 20 | } | 
| 21 | 21 | |
| 22 | 22 | return m | ... | ... | 
src/models/hero.go renamed to models/hero.go
| ... | ... | @@ -2,7 +2,7 @@ package models | 
| 2 | 2 | |
| 3 | 3 | import ( | 
| 4 | 4 | "pro2d/pb" | 
| 5 | - "pro2d/src/components/db" | |
| 5 | + "pro2d/utils/db" | |
| 6 | 6 | ) | 
| 7 | 7 | |
| 8 | 8 | type HeroModel struct { | 
| ... | ... | @@ -25,7 +25,7 @@ func NewHero(id string) *HeroModel { | 
| 25 | 25 | } | 
| 26 | 26 | m := &HeroModel{ | 
| 27 | 27 | Schema: db.NewSchema(id, h), | 
| 28 | - Hero: h, | |
| 28 | + Hero: h, | |
| 29 | 29 | } | 
| 30 | 30 | return m | 
| 31 | 31 | } | ... | ... | 
src/models/init.go renamed to models/init.go
src/models/init_test.go renamed to models/init_test.go
src/models/prop.go renamed to models/prop.go
| ... | ... | @@ -2,7 +2,7 @@ package models | 
| 2 | 2 | |
| 3 | 3 | import ( | 
| 4 | 4 | "pro2d/pb" | 
| 5 | - "pro2d/src/components/db" | |
| 5 | + "pro2d/utils/db" | |
| 6 | 6 | ) | 
| 7 | 7 | |
| 8 | 8 | type PropModels struct { | 
| ... | ... | @@ -16,7 +16,7 @@ func NewProp(id string) *PropModels { | 
| 16 | 16 | } | 
| 17 | 17 | m := &PropModels{ | 
| 18 | 18 | Schema: db.NewSchema(id, data), | 
| 19 | - Prop: data, | |
| 19 | + Prop: data, | |
| 20 | 20 | } | 
| 21 | 21 | |
| 22 | 22 | return m | ... | ... | 
src/models/role.go renamed to models/role.go
| ... | ... | @@ -2,11 +2,11 @@ package models | 
| 2 | 2 | |
| 3 | 3 | import ( | 
| 4 | 4 | "fmt" | 
| 5 | + "pro2d/common" | |
| 5 | 6 | "pro2d/pb" | 
| 6 | - "pro2d/src/common" | |
| 7 | - "pro2d/src/components/db" | |
| 8 | - "pro2d/src/components/logger" | |
| 9 | - "pro2d/src/utils" | |
| 7 | + "pro2d/utils" | |
| 8 | + "pro2d/utils/db" | |
| 9 | + "pro2d/utils/logger" | |
| 10 | 10 | "sync/atomic" | 
| 11 | 11 | ) | 
| 12 | 12 | |
| ... | ... | @@ -32,11 +32,11 @@ func RoleExistByUid(uid string) *RoleModel { | 
| 32 | 32 | |
| 33 | 33 | r := &RoleModel{ | 
| 34 | 34 | Schema: db.NewSchema(data.Id, data), | 
| 35 | - Role: data, | |
| 36 | - Heros: make(HeroMap), | |
| 37 | - Teams: new(TeamModel), | |
| 38 | - Equip: new(EquipModels), | |
| 39 | - Prop: new(PropModels), | |
| 35 | + Role: data, | |
| 36 | + Heros: make(HeroMap), | |
| 37 | + Teams: new(TeamModel), | |
| 38 | + Equip: new(EquipModels), | |
| 39 | + Prop: new(PropModels), | |
| 40 | 40 | } | 
| 41 | 41 | r.LoadAll() | 
| 42 | 42 | return r | 
| ... | ... | @@ -46,11 +46,11 @@ func NewRole(id string) *RoleModel { | 
| 46 | 46 | data := &pb.Role{Id: id} | 
| 47 | 47 | m := &RoleModel{ | 
| 48 | 48 | Schema: db.NewSchema(id, data), | 
| 49 | - Role: data, | |
| 50 | - Heros: make(HeroMap), | |
| 51 | - Teams: new(TeamModel), | |
| 52 | - Equip: new(EquipModels), | |
| 53 | - Prop: new(PropModels), | |
| 49 | + Role: data, | |
| 50 | + Heros: make(HeroMap), | |
| 51 | + Teams: new(TeamModel), | |
| 52 | + Equip: new(EquipModels), | |
| 53 | + Prop: new(PropModels), | |
| 54 | 54 | } | 
| 55 | 55 | return m | 
| 56 | 56 | } | ... | ... | 
src/models/role_test.go renamed to models/role_test.go
src/models/team.go renamed to models/team.go
| ... | ... | @@ -2,7 +2,7 @@ package models | 
| 2 | 2 | |
| 3 | 3 | import ( | 
| 4 | 4 | "pro2d/pb" | 
| 5 | - "pro2d/src/components/db" | |
| 5 | + "pro2d/utils/db" | |
| 6 | 6 | ) | 
| 7 | 7 | |
| 8 | 8 | type TeamModel struct { | 
| ... | ... | @@ -16,7 +16,7 @@ func NewTeam(id string) *TeamModel { | 
| 16 | 16 | } | 
| 17 | 17 | m := &TeamModel{ | 
| 18 | 18 | Schema: db.NewSchema(id, data), | 
| 19 | - Team: data, | |
| 19 | + Team: data, | |
| 20 | 20 | } | 
| 21 | 21 | |
| 22 | 22 | return m | ... | ... | 
src/plugin/RolePlugin.go renamed to plugin/RolePlugin.go
| ... | ... | @@ -2,21 +2,21 @@ package plugin | 
| 2 | 2 | |
| 3 | 3 | import ( | 
| 4 | 4 | "github.com/golang/protobuf/proto" | 
| 5 | + "pro2d/common/components" | |
| 5 | 6 | "pro2d/conf" | 
| 7 | + "pro2d/models" | |
| 6 | 8 | "pro2d/pb" | 
| 7 | - "pro2d/src/components/logger" | |
| 8 | - "pro2d/src/components/net" | |
| 9 | - "pro2d/src/models" | |
| 9 | + "pro2d/utils/logger" | |
| 10 | 10 | ) | 
| 11 | 11 | |
| 12 | -func HeartRpc(msg *net.MsgPkg) (int32, proto.Message) { | |
| 12 | +func HeartRpc(msg components.IMessage) (int32, proto.Message) { | |
| 13 | 13 | //msg.Conn.SetLastHeartCheckTime() | 
| 14 | 14 | return 0, nil | 
| 15 | 15 | } | 
| 16 | 16 | |
| 17 | -func CreateRpc(msg *net.MsgPkg) (int32, proto.Message) { | |
| 17 | +func CreateRpc(msg components.IMessage) (int32, proto.Message) { | |
| 18 | 18 | req := pb.CreateReq{} | 
| 19 | - if err := proto.Unmarshal(msg.Body, &req); err != nil { | |
| 19 | + if err := proto.Unmarshal(msg.GetData(), &req); err != nil { | |
| 20 | 20 | logger.Error("CreateRpc err: %v", err) | 
| 21 | 21 | return 1, nil | 
| 22 | 22 | } | 
| ... | ... | @@ -34,10 +34,10 @@ func CreateRpc(msg *net.MsgPkg) (int32, proto.Message) { | 
| 34 | 34 | return 0, nil | 
| 35 | 35 | } | 
| 36 | 36 | |
| 37 | -func LoginRpc(msg *net.MsgPkg) (int32, proto.Message) { | |
| 38 | - //logger.Debug("cmd: %v, msg: %s", msg.Head.Cmd, msg.Body) | |
| 37 | +func LoginRpc(msg components.IMessage) (int32, proto.Message) { | |
| 38 | + //logger.Debug("cmd: %v, msg: %s", msg.PBHead.Cmd, msg.Body) | |
| 39 | 39 | req := pb.LoginReq{} | 
| 40 | - if err := proto.Unmarshal(msg.Body, &req); err != nil { | |
| 40 | + if err := proto.Unmarshal(msg.GetData(), &req); err != nil { | |
| 41 | 41 | logger.Error("loginRpc err: %v", err) | 
| 42 | 42 | return 1, nil | 
| 43 | 43 | } | 
| ... | ... | @@ -49,7 +49,6 @@ func LoginRpc(msg *net.MsgPkg) (int32, proto.Message) { | 
| 49 | 49 | role.SetProperty("Device", req.Device) | 
| 50 | 50 | |
| 51 | 51 | |
| 52 | - msg.Conn.Role = role | |
| 53 | 52 | return 0, &pb.RoleRsp{ | 
| 54 | 53 | Role: role.Role, | 
| 55 | 54 | Hero: role.GetAllHero(), | ... | ... | 
src/plugin/protocode.go renamed to plugin/protocode.go
| 1 | 1 | package plugin | 
| 2 | 2 | |
| 3 | 3 | import ( | 
| 4 | + "pro2d/common/components" | |
| 4 | 5 | "pro2d/pb" | 
| 5 | - "pro2d/src/components/logger" | |
| 6 | - "pro2d/src/components/net" | |
| 6 | + "pro2d/utils/logger" | |
| 7 | 7 | ) | 
| 8 | 8 | |
| 9 | 9 | func init() { | 
| 10 | 10 | logger.Debug("init protocode...") | 
| 11 | - net.ActionMap = make(map[pb.ProtoCode]net.ActionHandler) | |
| 11 | + components.ActionMap = make(map[pb.ProtoCode]components.ActionHandler) | |
| 12 | 12 | |
| 13 | - net.ActionMap[pb.ProtoCode_HeartReq] = HeartRpc | |
| 14 | - net.ActionMap[pb.ProtoCode_LoginReq] = LoginRpc | |
| 15 | - net.ActionMap[pb.ProtoCode_CreateReq] = CreateRpc | |
| 13 | + components.ActionMap[pb.ProtoCode_HeartReq] = HeartRpc | |
| 14 | + components.ActionMap[pb.ProtoCode_LoginReq] = LoginRpc | |
| 15 | + components.ActionMap[pb.ProtoCode_CreateReq] = CreateRpc | |
| 16 | 16 | |
| 17 | 17 | } | ... | ... | 
src/components/net/conn.go deleted
| ... | ... | @@ -1,195 +0,0 @@ | 
| 1 | -package net | |
| 2 | - | |
| 3 | -import ( | |
| 4 | - "bufio" | |
| 5 | - "fmt" | |
| 6 | - "math" | |
| 7 | - "net" | |
| 8 | - "pro2d/src/common" | |
| 9 | - "pro2d/src/components/logger" | |
| 10 | - "pro2d/src/models" | |
| 11 | - "pro2d/src/utils" | |
| 12 | - "sync/atomic" | |
| 13 | -) | |
| 14 | - | |
| 15 | -type Head struct { | |
| 16 | - Length int32 | |
| 17 | - Cmd int32 | |
| 18 | - ErrCode int32 | |
| 19 | - PreField int32 | |
| 20 | -} | |
| 21 | - | |
| 22 | - | |
| 23 | -type Connection struct { | |
| 24 | - net.Conn | |
| 25 | - Id int | |
| 26 | - Server *Server | |
| 27 | - | |
| 28 | - scanner *bufio.Scanner | |
| 29 | - writer *bufio.Writer | |
| 30 | - | |
| 31 | - WBuffer chan []byte | |
| 32 | - | |
| 33 | - updateFunc chan func() | |
| 34 | - readFunc chan func() | |
| 35 | - | |
| 36 | - Quit chan *Connection | |
| 37 | - | |
| 38 | - Role *models.RoleModel | |
| 39 | - | |
| 40 | - nextCheckTime int64 //下一次检查的时间 | |
| 41 | - lastHeartCheckTime int64 //最后收消息时间 | |
| 42 | - heartTimeoutCount int //超时次数 | |
| 43 | -} | |
| 44 | - | |
| 45 | -type MsgPkg struct { | |
| 46 | - Head *Head | |
| 47 | - Body []byte | |
| 48 | - Conn *Connection | |
| 49 | -} | |
| 50 | - | |
| 51 | -func NewConn(id int, conn net.Conn, s *Server) *Connection { | |
| 52 | - return &Connection{ | |
| 53 | - Id: id, | |
| 54 | - Conn: conn, | |
| 55 | - Server: s, | |
| 56 | - | |
| 57 | - scanner: bufio.NewScanner(conn), | |
| 58 | - writer: bufio.NewWriter(conn), | |
| 59 | - WBuffer: make(chan []byte), | |
| 60 | - updateFunc: make(chan func()), | |
| 61 | - readFunc: make(chan func()), | |
| 62 | - Quit: make(chan *Connection), | |
| 63 | - lastHeartCheckTime: utils.Timex(), | |
| 64 | - heartTimeoutCount: 0, | |
| 65 | - } | |
| 66 | -} | |
| 67 | - | |
| 68 | -func (c *Connection) write() { | |
| 69 | - defer c.Quiting() | |
| 70 | - | |
| 71 | - for msg := range c.WBuffer { | |
| 72 | - n, err := c.writer.Write(msg) | |
| 73 | - if err != nil{ | |
| 74 | - logger.Error("write fail err: " + err.Error(), "n: ", n) | |
| 75 | - return | |
| 76 | - } | |
| 77 | - if err := c.writer.Flush(); err != nil { | |
| 78 | - logger.Error("write Flush fail err: " + err.Error()) | |
| 79 | - return | |
| 80 | - } | |
| 81 | - } | |
| 82 | -} | |
| 83 | - | |
| 84 | -func (c *Connection) read() { | |
| 85 | - defer c.Quiting() | |
| 86 | - c.scanner.Split(ParseMsg) | |
| 87 | - | |
| 88 | - for c.scanner.Scan() { | |
| 89 | - req, err := DecodeMsg(c.scanner.Bytes()) | |
| 90 | - if err != nil { | |
| 91 | - return | |
| 92 | - } | |
| 93 | - | |
| 94 | - req.Conn = c | |
| 95 | - c.readFunc <- func() { | |
| 96 | - c.Server.DoMsgHandler(req) | |
| 97 | - } | |
| 98 | - | |
| 99 | - atomic.StoreInt64(&c.lastHeartCheckTime, utils.Timex()) | |
| 100 | - | |
| 101 | - //备注,可以在当前协程处理当条请求(如下, 实现很简单,已经删除),也可以丢到协程池里处理任务(如上),还未对比效果。 | |
| 102 | - //c.Server.OnRecv(req) | |
| 103 | - } | |
| 104 | - | |
| 105 | - if err := c.scanner.Err(); err != nil { | |
| 106 | - fmt.Printf("scanner.err: %s\n", err.Error()) | |
| 107 | - return | |
| 108 | - } | |
| 109 | -} | |
| 110 | - | |
| 111 | -func (c *Connection) checkHeartBeat(now int64) { | |
| 112 | - lastHeartCheckTime := atomic.LoadInt64(&c.lastHeartCheckTime) | |
| 113 | - logger.Debug("checkHeartBeat ID: %d, last: %d, now: %d", c.Id, lastHeartCheckTime, now) | |
| 114 | - if math.Abs(float64(lastHeartCheckTime - now)) > common.HeartTimerInterval { | |
| 115 | - c.heartTimeoutCount++ | |
| 116 | - if c.heartTimeoutCount >= common.HeartTimeoutCountMax { | |
| 117 | - c.Quiting() | |
| 118 | - return | |
| 119 | - } | |
| 120 | - logger.Debug("timeout count: %d", c.heartTimeoutCount) | |
| 121 | - }else { | |
| 122 | - c.heartTimeoutCount = 0 | |
| 123 | - } | |
| 124 | -} | |
| 125 | - | |
| 126 | -func (c *Connection) update() { | |
| 127 | - nextCheckTime := atomic.LoadInt64(&c.nextCheckTime) | |
| 128 | - now := utils.Timex() | |
| 129 | - if now >= nextCheckTime { | |
| 130 | - //检查心跳 | |
| 131 | - c.checkHeartBeat(now) | |
| 132 | - nextCheckTime = now + common.HeartTimerInterval | |
| 133 | - atomic.StoreInt64(&c.nextCheckTime, nextCheckTime) | |
| 134 | - } | |
| 135 | - | |
| 136 | - c.updateFunc <- func() { | |
| 137 | - if c.Role != nil { | |
| 138 | - //role 恢复数据 | |
| 139 | - c.Role.OnRecoverTimer(now) | |
| 140 | - } | |
| 141 | - } | |
| 142 | -} | |
| 143 | - | |
| 144 | -func (c *Connection) flush() { | |
| 145 | - defer c.Stop() | |
| 146 | - for { | |
| 147 | - select { | |
| 148 | - case rf := <- c.readFunc: | |
| 149 | - rf() | |
| 150 | - case uf := <- c.updateFunc: | |
| 151 | - uf() | |
| 152 | - case <- c.Quit: | |
| 153 | - return | |
| 154 | - } | |
| 155 | - } | |
| 156 | -} | |
| 157 | - | |
| 158 | -func (c *Connection) Start() { | |
| 159 | - go c.write() | |
| 160 | - go c.read() | |
| 161 | - c.flush() | |
| 162 | -} | |
| 163 | - | |
| 164 | -func (c *Connection) Stop() { | |
| 165 | - logger.Debug("ID: %d close", c.Id) | |
| 166 | - c.Conn.Close() | |
| 167 | - if c.Role != nil { | |
| 168 | - c.Role.OnOfflineEvent() | |
| 169 | - } | |
| 170 | - | |
| 171 | - c.Server.OnClose(c) | |
| 172 | -} | |
| 173 | - | |
| 174 | -func (c *Connection) Quiting() { | |
| 175 | - c.Quit <- c | |
| 176 | -} | |
| 177 | - | |
| 178 | -func (c *Connection) SendMsgByCode(errCode int32, cmd int32, data []byte){ | |
| 179 | - h := &Head{ | |
| 180 | - Length: int32(common.HEADLEN + len(data)), | |
| 181 | - Cmd: cmd, | |
| 182 | - ErrCode: errCode, | |
| 183 | - PreField: 0, | |
| 184 | - } | |
| 185 | - pkg := &MsgPkg{ | |
| 186 | - Head: h, | |
| 187 | - Body: data, | |
| 188 | - } | |
| 189 | - buf, err := EncodeMsg(pkg) | |
| 190 | - if err != nil { | |
| 191 | - logger.Error("SendMsg error: %v", err) | |
| 192 | - return | |
| 193 | - } | |
| 194 | - c.WBuffer <- buf | |
| 195 | -} | |
| 196 | 0 | \ No newline at end of file | 
src/components/net/msg.go deleted
| ... | ... | @@ -1,57 +0,0 @@ | 
| 1 | -package net | |
| 2 | - | |
| 3 | -import ( | |
| 4 | - "bytes" | |
| 5 | - "encoding/binary" | |
| 6 | - "fmt" | |
| 7 | - "pro2d/src/common" | |
| 8 | -) | |
| 9 | - | |
| 10 | -func ParseMsg (data []byte, atEOF bool) (advance int, token []byte, err error) { | |
| 11 | - // 表示我们已经扫描到结尾了 | |
| 12 | - if atEOF && len(data) == 0 { | |
| 13 | - return 0, nil, nil | |
| 14 | - } | |
| 15 | - if !atEOF && len(data) >= common.HEADLEN { //4字节数据包长度 4字节指令 | |
| 16 | - length := int32(0) | |
| 17 | - binary.Read(bytes.NewReader(data[0:4]), binary.BigEndian, &length) | |
| 18 | - if length <= 0 { | |
| 19 | - return 0, nil, fmt.Errorf("length is 0") | |
| 20 | - } | |
| 21 | - if int(length) <= len(data) { | |
| 22 | - return int(length) , data[:int(length)], nil | |
| 23 | - } | |
| 24 | - return 0 , nil, nil | |
| 25 | - } | |
| 26 | - if atEOF { | |
| 27 | - return len(data), data, nil | |
| 28 | - } | |
| 29 | - return 0, nil, nil | |
| 30 | -} | |
| 31 | - | |
| 32 | - | |
| 33 | -func DecodeMsg(data []byte) (*MsgPkg, error) { | |
| 34 | - h := &Head{} | |
| 35 | - err := binary.Read(bytes.NewReader(data), binary.BigEndian, h) | |
| 36 | - if err != nil { | |
| 37 | - return nil, err | |
| 38 | - } | |
| 39 | - return &MsgPkg{ | |
| 40 | - Head: h, | |
| 41 | - Body: data[common.HEADLEN:], | |
| 42 | - },nil | |
| 43 | -} | |
| 44 | - | |
| 45 | -func EncodeMsg(pkg *MsgPkg) ([]byte, error) { | |
| 46 | - buf := &bytes.Buffer{} | |
| 47 | - err := binary.Write(buf, binary.BigEndian, pkg.Head) | |
| 48 | - if err != nil { | |
| 49 | - return nil, err | |
| 50 | - } | |
| 51 | - | |
| 52 | - err = binary.Write(buf, binary.BigEndian, pkg.Body) | |
| 53 | - if err != nil { | |
| 54 | - return nil, err | |
| 55 | - } | |
| 56 | - return buf.Bytes(), nil | |
| 57 | -} | |
| 58 | 0 | \ No newline at end of file | 
src/components/net/server.go deleted
| ... | ... | @@ -1,131 +0,0 @@ | 
| 1 | -package net | |
| 2 | - | |
| 3 | -import ( | |
| 4 | - "context" | |
| 5 | - "fmt" | |
| 6 | - "github.com/golang/protobuf/proto" | |
| 7 | - "net" | |
| 8 | - "plugin" | |
| 9 | - "pro2d/conf" | |
| 10 | - "pro2d/pb" | |
| 11 | - "pro2d/src/components/db" | |
| 12 | - "pro2d/src/components/etcd" | |
| 13 | - "pro2d/src/components/logger" | |
| 14 | - "pro2d/src/components/timewheel" | |
| 15 | - "pro2d/src/models" | |
| 16 | - "sync" | |
| 17 | - "time" | |
| 18 | -) | |
| 19 | - | |
| 20 | -type ActionHandler func (msg *MsgPkg) (int32, proto.Message) | |
| 21 | -var ActionMap map[pb.ProtoCode]ActionHandler | |
| 22 | - | |
| 23 | -type Server struct { | |
| 24 | - SConf *conf.SConf | |
| 25 | - Clients *sync.Map | |
| 26 | - EtcdClient *etcd.EtcdClient | |
| 27 | -} | |
| 28 | - | |
| 29 | -func NewServer(sConf *conf.SConf) *Server { | |
| 30 | - return &Server{ | |
| 31 | - SConf: sConf, | |
| 32 | - Clients: new(sync.Map), | |
| 33 | - EtcdClient: new(etcd.EtcdClient), | |
| 34 | - } | |
| 35 | -} | |
| 36 | - | |
| 37 | -func (s *Server) DoMsgHandler(msg *MsgPkg) { | |
| 38 | - if md, ok := ActionMap[pb.ProtoCode(msg.Head.Cmd)]; ok { | |
| 39 | - logger.Debug("protocode handler: %d", msg.Head.Cmd) | |
| 40 | - errCode, protomsg := md(msg) | |
| 41 | - rsp, err := proto.Marshal(protomsg) | |
| 42 | - fmt.Printf("errCode: %d, protomsg:%v\n", errCode, protomsg) | |
| 43 | - if err != nil { | |
| 44 | - msg.Conn.SendMsgByCode(-100, msg.Head.Cmd, nil) | |
| 45 | - return | |
| 46 | - } | |
| 47 | - msg.Conn.SendMsgByCode(errCode, msg.Head.Cmd, rsp) | |
| 48 | - return | |
| 49 | - } | |
| 50 | - logger.Error("protocode not handler: %d", msg.Head.Cmd) | |
| 51 | -} | |
| 52 | - | |
| 53 | -func (s *Server) OnClose(conn *Connection) { | |
| 54 | - s.Clients.Delete(conn.Id) | |
| 55 | -} | |
| 56 | - | |
| 57 | -func (s *Server) LoadPlugin() { | |
| 58 | - //重新加载 | |
| 59 | - _, err:=plugin.Open(conf.GlobalConf.GameConf.PluginPath) | |
| 60 | - if err != nil { | |
| 61 | - logger.Error("load plugin err: %v, %s", err, conf.GlobalConf.GameConf.PluginPath) | |
| 62 | - return | |
| 63 | - } | |
| 64 | - logger.Debug("load plugin success") | |
| 65 | -} | |
| 66 | - | |
| 67 | -func (s *Server) handleTimeOut() { | |
| 68 | - s.Clients.Range(func(key, value interface{}) bool { | |
| 69 | - client := value.(*Connection) | |
| 70 | - client.update() | |
| 71 | - return true | |
| 72 | - }) | |
| 73 | - | |
| 74 | - timewheel.TimeOut(1*time.Second, s.handleTimeOut) | |
| 75 | -} | |
| 76 | - | |
| 77 | -func (s *Server)Start() error { | |
| 78 | - //mongo 初始化 | |
| 79 | - db.MongoDatabase = db.MongoClient.Database(conf.GlobalConf.GameConf.DBName) | |
| 80 | - models.InitGameServerModels() | |
| 81 | - | |
| 82 | - //Etcd 初始化 | |
| 83 | - var err error | |
| 84 | - s.EtcdClient, err = etcd.NewEtcdClient(conf.GlobalConf.Etcd) | |
| 85 | - if err != nil { | |
| 86 | - return err | |
| 87 | - } | |
| 88 | - s.EtcdClient.PutWithLeasePrefix(conf.GlobalConf.GameConf.Name, conf.GlobalConf.GameConf.ID, fmt.Sprintf("%s:%d", conf.GlobalConf.GameConf.IP, conf.GlobalConf.GameConf.Port), 5) | |
| 89 | - | |
| 90 | - //初始化plugin | |
| 91 | - //_, err = plugin.Open(conf.GlobalConf.GameConf.PluginPath) | |
| 92 | - //if err != nil { | |
| 93 | - // return err | |
| 94 | - //} | |
| 95 | - | |
| 96 | - port := fmt.Sprintf(":%d", s.SConf.Port) | |
| 97 | - l, err := net.Listen("tcp", port) | |
| 98 | - if err != nil { | |
| 99 | - return err | |
| 100 | - } | |
| 101 | - | |
| 102 | - //启动定时器 | |
| 103 | - s.handleTimeOut() | |
| 104 | - | |
| 105 | - //监听端口 | |
| 106 | - logger.Debug("listen on %s\n", port) | |
| 107 | - id := 0 | |
| 108 | - for { | |
| 109 | - conn, err := l.Accept() | |
| 110 | - if err != nil { | |
| 111 | - return err | |
| 112 | - } | |
| 113 | - | |
| 114 | - id++ | |
| 115 | - client := NewConn(id, conn, s) | |
| 116 | - s.Clients.Store(id, client) | |
| 117 | - go client.Start() | |
| 118 | - } | |
| 119 | -} | |
| 120 | - | |
| 121 | -func (s *Server)Stop() { | |
| 122 | - timewheel.StopTimer() | |
| 123 | - | |
| 124 | - s.Clients.Range(func(key, value interface{}) bool { | |
| 125 | - client := value.(*Connection) | |
| 126 | - client.Quiting() | |
| 127 | - return true | |
| 128 | - }) | |
| 129 | - | |
| 130 | - db.MongoClient.Disconnect(context.TODO()) | |
| 131 | -} | |
| 132 | 0 | \ No newline at end of file | 
src/components/db/mongo.go renamed to utils/db/mongo.go
src/components/db/redis.go renamed to utils/db/redis.go
src/components/db/schema.go renamed to utils/db/schema.go
src/components/etcd/etcd.go renamed to utils/etcd/etcd.go
src/components/etcd/etcd_test.go renamed to utils/etcd/etcd_test.go
src/components/logger/README.md renamed to utils/logger/README.md
src/components/logger/conn.go renamed to utils/logger/conn.go
src/components/logger/console.go renamed to utils/logger/console.go
src/components/logger/file.go renamed to utils/logger/file.go
src/components/logger/log.go renamed to utils/logger/log.go
src/utils/snowflake.go renamed to utils/snowflake.go
src/utils/utils.go renamed to utils/utils.go