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,12 +7,12 @@ gen: | ||
7 | protoc-go-inject-tag -input=./pb/*.pb.go | 7 | protoc-go-inject-tag -input=./pb/*.pb.go |
8 | 8 | ||
9 | test: | 9 | test: |
10 | - go run test/client.go | 10 | + go run cmd/test/client.go |
11 | http: | 11 | http: |
12 | - go run -race cmd/http.go | 12 | + go run -race cmd/httpserver/*.go |
13 | 13 | ||
14 | game: | 14 | game: |
15 | - go run -race cmd/game.go | 15 | + go run -race cmd/gameserver/*.go |
16 | build: | 16 | build: |
17 | go build -race -o bin/account cmd/http.go | 17 | go build -race -o bin/account cmd/http.go |
18 | go build -race -o bin/game cmd/game.go | 18 | go build -race -o bin/game cmd/game.go |
cmd/game.go deleted
@@ -1,41 +0,0 @@ | @@ -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 @@ | @@ -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 @@ | @@ -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 | import ( | 3 | import ( |
4 | "github.com/gin-gonic/gin" | 4 | "github.com/gin-gonic/gin" |
5 | "pro2d/conf" | 5 | "pro2d/conf" |
6 | + "pro2d/models" | ||
6 | "pro2d/pb" | 7 | "pro2d/pb" |
7 | - "pro2d/src/components/net" | ||
8 | - "pro2d/src/models" | ||
9 | - "pro2d/src/utils" | 8 | + "pro2d/utils" |
10 | ) | 9 | ) |
11 | 10 | ||
12 | type AccountAction struct { | 11 | type AccountAction struct { |
13 | - HttpServer *net.HttpServer | 12 | + HttpServer *AccountServer |
14 | } | 13 | } |
15 | 14 | ||
16 | func (h *AccountAction) Register(c *gin.Context) (int, interface{}){ | 15 | func (h *AccountAction) Register(c *gin.Context) (int, interface{}){ |
cmd/http.go renamed to cmd/httpserver/http.go
1 | package main | 1 | package main |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | + "fmt" | ||
4 | "os" | 5 | "os" |
5 | "os/signal" | 6 | "os/signal" |
7 | + "pro2d/common/components" | ||
8 | + "pro2d/conf" | ||
6 | _ "pro2d/conf" | 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 | "syscall" | 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 | func main() { | 41 | func main() { |
14 | err := make(chan error) | 42 | err := make(chan error) |
15 | stopChan := make(chan os.Signal) | 43 | stopChan := make(chan os.Signal) |
16 | signal.Notify(stopChan, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL) | 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 | go func() { | 48 | go func() { |
21 | err <- web.Start() | 49 | err <- web.Start() |
22 | }() | 50 | }() |
@@ -26,5 +54,6 @@ func main() { | @@ -26,5 +54,6 @@ func main() { | ||
26 | logger.Error("game server error: %v", e) | 54 | logger.Error("game server error: %v", e) |
27 | case <-stopChan: | 55 | case <-stopChan: |
28 | logger.Debug("game stop") | 56 | logger.Debug("game stop") |
57 | + web.Stop() | ||
29 | } | 58 | } |
30 | } | 59 | } |
31 | \ No newline at end of file | 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 | import ( | 3 | import ( |
4 | "github.com/gin-gonic/gin" | 4 | "github.com/gin-gonic/gin" |
5 | + "pro2d/common/components" | ||
5 | "testing" | 6 | "testing" |
6 | ) | 7 | ) |
7 | 8 | ||
@@ -16,7 +17,7 @@ func (h *HttpAction) PrintB(c *gin.Context) (int, interface{}) { | @@ -16,7 +17,7 @@ func (h *HttpAction) PrintB(c *gin.Context) (int, interface{}) { | ||
16 | } | 17 | } |
17 | 18 | ||
18 | func TestHttpServer_Start(t *testing.T) { | 19 | func TestHttpServer_Start(t *testing.T) { |
19 | - web := NewHttpServer("v1") | 20 | + web := components.NewHttpServer("v1") |
20 | web.BindHandler(&HttpAction{}) | 21 | web.BindHandler(&HttpAction{}) |
21 | web.Start() | 22 | web.Start() |
22 | } | 23 | } |
23 | \ No newline at end of file | 24 | \ No newline at end of file |
test/client.go renamed to cmd/test/client.go
@@ -6,17 +6,17 @@ import ( | @@ -6,17 +6,17 @@ import ( | ||
6 | "encoding/binary" | 6 | "encoding/binary" |
7 | "github.com/golang/protobuf/proto" | 7 | "github.com/golang/protobuf/proto" |
8 | "net" | 8 | "net" |
9 | + "pro2d/common/components" | ||
9 | "pro2d/pb" | 10 | "pro2d/pb" |
10 | - "pro2d/src/components/logger" | ||
11 | - net2 "pro2d/src/components/net" | 11 | + "pro2d/utils/logger" |
12 | "time" | 12 | "time" |
13 | ) | 13 | ) |
14 | 14 | ||
15 | func main() { | 15 | func main() { |
16 | 16 | ||
17 | - head := &net2.Head{ | 17 | + head := &components.PBHead{ |
18 | Length: 0, | 18 | Length: 0, |
19 | - Cmd: int32(pb.ProtoCode_LoginReq), | 19 | + Cmd: uint32(pb.ProtoCode_LoginReq), |
20 | ErrCode: 0, | 20 | ErrCode: 0, |
21 | PreField: 0, | 21 | PreField: 0, |
22 | } | 22 | } |
@@ -27,11 +27,11 @@ func main() { | @@ -27,11 +27,11 @@ func main() { | ||
27 | } | 27 | } |
28 | l, _ :=proto.Marshal(loginReq) | 28 | l, _ :=proto.Marshal(loginReq) |
29 | 29 | ||
30 | - b := net2.MsgPkg{ | 30 | + b := components.PBMessage{ |
31 | Head: head, | 31 | Head: head, |
32 | Body: l, | 32 | Body: l, |
33 | } | 33 | } |
34 | - head.Length = int32(16 + len(b.Body)) | 34 | + head.Length = uint32(16 + len(b.Body)) |
35 | buf := &bytes.Buffer{} | 35 | buf := &bytes.Buffer{} |
36 | err := binary.Write(buf, binary.BigEndian, head) | 36 | err := binary.Write(buf, binary.BigEndian, head) |
37 | if err != nil { | 37 | if err != nil { |
@@ -46,7 +46,7 @@ func main() { | @@ -46,7 +46,7 @@ func main() { | ||
46 | return | 46 | return |
47 | } | 47 | } |
48 | 48 | ||
49 | - client, err := net.Dial("tcp", "localhost:8849") | 49 | + client, err := net.Dial("tcp", "localhost:8850") |
50 | if err != nil { | 50 | if err != nil { |
51 | logger.Error(err) | 51 | logger.Error(err) |
52 | return | 52 | return |
test/client_test.go renamed to cmd/test/client_test.go
@@ -0,0 +1,122 @@ | @@ -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 | import ( | 3 | import ( |
4 | - "fmt" | ||
5 | "github.com/gin-gonic/gin" | 4 | "github.com/gin-gonic/gin" |
6 | "net/http" | 5 | "net/http" |
7 | - "pro2d/conf" | ||
8 | - "pro2d/src/components/db" | ||
9 | - "pro2d/src/components/etcd" | ||
10 | - "pro2d/src/models" | ||
11 | "reflect" | 6 | "reflect" |
12 | "strings" | 7 | "strings" |
13 | ) | 8 | ) |
14 | 9 | ||
15 | type HttpServer struct { | 10 | type HttpServer struct { |
11 | + IHttp | ||
16 | version string | 12 | version string |
17 | port []string | 13 | port []string |
18 | - EtcdClient *etcd.EtcdClient | ||
19 | - | ||
20 | Handler interface{} | 14 | Handler interface{} |
21 | } | 15 | } |
22 | 16 | ||
@@ -30,6 +24,10 @@ func NewHttpServer(version string, port ...string) *HttpServer { | @@ -30,6 +24,10 @@ func NewHttpServer(version string, port ...string) *HttpServer { | ||
30 | return &HttpServer{version: version, port: port} | 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 | func (h *HttpServer)HandlerFuncObj(tvl, obj reflect.Value) gin.HandlerFunc { | 31 | func (h *HttpServer)HandlerFuncObj(tvl, obj reflect.Value) gin.HandlerFunc { |
34 | return func(c *gin.Context) { | 32 | return func(c *gin.Context) { |
35 | v := tvl.Call([]reflect.Value{obj, reflect.ValueOf(c)}) | 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,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 | func (h *HttpServer) BindHandler(handler interface{}) { | 42 | func (h *HttpServer) BindHandler(handler interface{}) { |
49 | h.Handler = handler | 43 | h.Handler = handler |
50 | } | 44 | } |
51 | 45 | ||
52 | func (h *HttpServer) Start() error { | 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 | //gin初始化 | 47 | //gin初始化 |
66 | r := gin.Default() | 48 | r := gin.Default() |
67 | r.GET("/ping", Pong) | 49 | r.GET("/ping", Pong) |
@@ -0,0 +1,68 @@ | @@ -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 | \ No newline at end of file | 69 | \ No newline at end of file |
@@ -0,0 +1,134 @@ | @@ -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 | \ No newline at end of file | 135 | \ No newline at end of file |
@@ -0,0 +1,126 @@ | @@ -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 | import ( | 3 | import ( |
4 | "container/list" | 4 | "container/list" |
5 | - "pro2d/src/common" | ||
6 | - "pro2d/src/components/workpool" | 5 | + "pro2d/common" |
7 | "sync" | 6 | "sync" |
8 | "sync/atomic" | 7 | "sync/atomic" |
9 | "time" | 8 | "time" |
@@ -73,16 +72,16 @@ type TimeWheel struct { | @@ -73,16 +72,16 @@ type TimeWheel struct { | ||
73 | t [4][TimeLevel]*bucket | 72 | t [4][TimeLevel]*bucket |
74 | time uint32 | 73 | time uint32 |
75 | 74 | ||
76 | - WorkPool *workpool.WorkPool | 75 | + WorkPool *WorkPool |
77 | exit chan struct{} | 76 | exit chan struct{} |
78 | } | 77 | } |
79 | 78 | ||
80 | func NewTimeWheel() *TimeWheel { | 79 | func NewTimeWheel() *TimeWheel { |
81 | tw := &TimeWheel{ | 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 | for i :=0; i < TimeNear; i++ { | 86 | for i :=0; i < TimeNear; i++ { |
88 | tw.near[i] = newBucket() | 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,8 +5,9 @@ const ( | ||
5 | WorkerPoolSize = 10 | 5 | WorkerPoolSize = 10 |
6 | MaxTaskPerWorker = 100 | 6 | MaxTaskPerWorker = 100 |
7 | 7 | ||
8 | - //包头 | ||
9 | - HEADLEN = 16 | 8 | + //最大包大 |
9 | + MaxPacketLength = 10 * 1024 * 1024 | ||
10 | + MaxMsgChan = 100 | ||
10 | 11 | ||
11 | //jwt | 12 | //jwt |
12 | Pro2DTokenSignedString = "Pro2DSecret" | 13 | Pro2DTokenSignedString = "Pro2DSecret" |
@@ -19,6 +20,6 @@ const ( | @@ -19,6 +20,6 @@ const ( | ||
19 | HeartTimerInterval = 5 //s | 20 | HeartTimerInterval = 5 //s |
20 | HeartTimeoutCountMax = 20 //最大超时次数 | 21 | HeartTimeoutCountMax = 20 //最大超时次数 |
21 | 22 | ||
22 | - //保存数据时间剑客 | 23 | + //保存数据时间 |
23 | SaveDataInterval = 5 //s | 24 | SaveDataInterval = 5 //s |
24 | ) | 25 | ) |
conf/conf.go
@@ -5,9 +5,9 @@ import ( | @@ -5,9 +5,9 @@ import ( | ||
5 | "fmt" | 5 | "fmt" |
6 | "gopkg.in/yaml.v3" | 6 | "gopkg.in/yaml.v3" |
7 | "io/ioutil" | 7 | "io/ioutil" |
8 | - "pro2d/src/components/db" | ||
9 | - "pro2d/src/components/logger" | ||
10 | - "pro2d/src/utils" | 8 | + "pro2d/utils" |
9 | + "pro2d/utils/db" | ||
10 | + "pro2d/utils/logger" | ||
11 | "strings" | 11 | "strings" |
12 | ) | 12 | ) |
13 | 13 |
conf/conf.yaml
@@ -28,7 +28,7 @@ server_game: | @@ -28,7 +28,7 @@ server_game: | ||
28 | id: "1" | 28 | id: "1" |
29 | name: "game" | 29 | name: "game" |
30 | ip: "192.168.0.206" | 30 | ip: "192.168.0.206" |
31 | - port: 8849 | 31 | + port: 8850 |
32 | dbname: "game" | 32 | dbname: "game" |
33 | pool_size: 1 | 33 | pool_size: 1 |
34 | plugin_path: "./bin/plugin.so" | 34 | plugin_path: "./bin/plugin.so" |
src/models/account.go renamed to models/account.go
@@ -2,7 +2,7 @@ package models | @@ -2,7 +2,7 @@ package models | ||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "pro2d/pb" | 4 | "pro2d/pb" |
5 | - "pro2d/src/components/db" | 5 | + "pro2d/utils/db" |
6 | ) | 6 | ) |
7 | 7 | ||
8 | type AccountModel struct { | 8 | type AccountModel struct { |
@@ -23,7 +23,7 @@ func NewAccount(phone string) *AccountModel { | @@ -23,7 +23,7 @@ func NewAccount(phone string) *AccountModel { | ||
23 | Phone: phone, | 23 | Phone: phone, |
24 | } | 24 | } |
25 | account := &AccountModel{ | 25 | account := &AccountModel{ |
26 | - Schema: db.NewSchema(phone, ac), | 26 | + Schema: db.NewSchema(phone, ac), |
27 | Account: ac, | 27 | Account: ac, |
28 | } | 28 | } |
29 | 29 |
src/models/equip.go renamed to models/equip.go
@@ -2,7 +2,7 @@ package models | @@ -2,7 +2,7 @@ package models | ||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "pro2d/pb" | 4 | "pro2d/pb" |
5 | - "pro2d/src/components/db" | 5 | + "pro2d/utils/db" |
6 | ) | 6 | ) |
7 | 7 | ||
8 | type EquipModels struct { | 8 | type EquipModels struct { |
@@ -16,7 +16,7 @@ func NewEquip(id string) *EquipModels { | @@ -16,7 +16,7 @@ func NewEquip(id string) *EquipModels { | ||
16 | } | 16 | } |
17 | m := &EquipModels{ | 17 | m := &EquipModels{ |
18 | Schema: db.NewSchema(id, data), | 18 | Schema: db.NewSchema(id, data), |
19 | - Equip: data, | 19 | + Equip: data, |
20 | } | 20 | } |
21 | 21 | ||
22 | return m | 22 | return m |
src/models/hero.go renamed to models/hero.go
@@ -2,7 +2,7 @@ package models | @@ -2,7 +2,7 @@ package models | ||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "pro2d/pb" | 4 | "pro2d/pb" |
5 | - "pro2d/src/components/db" | 5 | + "pro2d/utils/db" |
6 | ) | 6 | ) |
7 | 7 | ||
8 | type HeroModel struct { | 8 | type HeroModel struct { |
@@ -25,7 +25,7 @@ func NewHero(id string) *HeroModel { | @@ -25,7 +25,7 @@ func NewHero(id string) *HeroModel { | ||
25 | } | 25 | } |
26 | m := &HeroModel{ | 26 | m := &HeroModel{ |
27 | Schema: db.NewSchema(id, h), | 27 | Schema: db.NewSchema(id, h), |
28 | - Hero: h, | 28 | + Hero: h, |
29 | } | 29 | } |
30 | return m | 30 | return m |
31 | } | 31 | } |
src/models/init.go renamed to models/init.go
@@ -2,9 +2,9 @@ package models | @@ -2,9 +2,9 @@ package models | ||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "pro2d/pb" | 4 | "pro2d/pb" |
5 | - "pro2d/src/components/db" | ||
6 | - "pro2d/src/components/logger" | ||
7 | - "pro2d/src/utils" | 5 | + "pro2d/utils" |
6 | + "pro2d/utils/db" | ||
7 | + "pro2d/utils/logger" | ||
8 | ) | 8 | ) |
9 | 9 | ||
10 | func InitDoc(schema ...interface{}) { | 10 | func InitDoc(schema ...interface{}) { |
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,7 +2,7 @@ package models | ||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "pro2d/pb" | 4 | "pro2d/pb" |
5 | - "pro2d/src/components/db" | 5 | + "pro2d/utils/db" |
6 | ) | 6 | ) |
7 | 7 | ||
8 | type PropModels struct { | 8 | type PropModels struct { |
@@ -16,7 +16,7 @@ func NewProp(id string) *PropModels { | @@ -16,7 +16,7 @@ func NewProp(id string) *PropModels { | ||
16 | } | 16 | } |
17 | m := &PropModels{ | 17 | m := &PropModels{ |
18 | Schema: db.NewSchema(id, data), | 18 | Schema: db.NewSchema(id, data), |
19 | - Prop: data, | 19 | + Prop: data, |
20 | } | 20 | } |
21 | 21 | ||
22 | return m | 22 | return m |
src/models/role.go renamed to models/role.go
@@ -2,11 +2,11 @@ package models | @@ -2,11 +2,11 @@ package models | ||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "fmt" | 4 | "fmt" |
5 | + "pro2d/common" | ||
5 | "pro2d/pb" | 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 | "sync/atomic" | 10 | "sync/atomic" |
11 | ) | 11 | ) |
12 | 12 | ||
@@ -32,11 +32,11 @@ func RoleExistByUid(uid string) *RoleModel { | @@ -32,11 +32,11 @@ func RoleExistByUid(uid string) *RoleModel { | ||
32 | 32 | ||
33 | r := &RoleModel{ | 33 | r := &RoleModel{ |
34 | Schema: db.NewSchema(data.Id, data), | 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 | r.LoadAll() | 41 | r.LoadAll() |
42 | return r | 42 | return r |
@@ -46,11 +46,11 @@ func NewRole(id string) *RoleModel { | @@ -46,11 +46,11 @@ func NewRole(id string) *RoleModel { | ||
46 | data := &pb.Role{Id: id} | 46 | data := &pb.Role{Id: id} |
47 | m := &RoleModel{ | 47 | m := &RoleModel{ |
48 | Schema: db.NewSchema(id, data), | 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 | return m | 55 | return m |
56 | } | 56 | } |
src/models/role_test.go renamed to models/role_test.go
@@ -4,9 +4,9 @@ import ( | @@ -4,9 +4,9 @@ import ( | ||
4 | "fmt" | 4 | "fmt" |
5 | _ "pro2d/conf" | 5 | _ "pro2d/conf" |
6 | "pro2d/pb" | 6 | "pro2d/pb" |
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 | "testing" | 10 | "testing" |
11 | ) | 11 | ) |
12 | 12 |
src/models/team.go renamed to models/team.go
@@ -2,7 +2,7 @@ package models | @@ -2,7 +2,7 @@ package models | ||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "pro2d/pb" | 4 | "pro2d/pb" |
5 | - "pro2d/src/components/db" | 5 | + "pro2d/utils/db" |
6 | ) | 6 | ) |
7 | 7 | ||
8 | type TeamModel struct { | 8 | type TeamModel struct { |
@@ -16,7 +16,7 @@ func NewTeam(id string) *TeamModel { | @@ -16,7 +16,7 @@ func NewTeam(id string) *TeamModel { | ||
16 | } | 16 | } |
17 | m := &TeamModel{ | 17 | m := &TeamModel{ |
18 | Schema: db.NewSchema(id, data), | 18 | Schema: db.NewSchema(id, data), |
19 | - Team: data, | 19 | + Team: data, |
20 | } | 20 | } |
21 | 21 | ||
22 | return m | 22 | return m |
src/plugin/RolePlugin.go renamed to plugin/RolePlugin.go
@@ -2,21 +2,21 @@ package plugin | @@ -2,21 +2,21 @@ package plugin | ||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "github.com/golang/protobuf/proto" | 4 | "github.com/golang/protobuf/proto" |
5 | + "pro2d/common/components" | ||
5 | "pro2d/conf" | 6 | "pro2d/conf" |
7 | + "pro2d/models" | ||
6 | "pro2d/pb" | 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 | //msg.Conn.SetLastHeartCheckTime() | 13 | //msg.Conn.SetLastHeartCheckTime() |
14 | return 0, nil | 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 | req := pb.CreateReq{} | 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 | logger.Error("CreateRpc err: %v", err) | 20 | logger.Error("CreateRpc err: %v", err) |
21 | return 1, nil | 21 | return 1, nil |
22 | } | 22 | } |
@@ -34,10 +34,10 @@ func CreateRpc(msg *net.MsgPkg) (int32, proto.Message) { | @@ -34,10 +34,10 @@ func CreateRpc(msg *net.MsgPkg) (int32, proto.Message) { | ||
34 | return 0, nil | 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 | req := pb.LoginReq{} | 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 | logger.Error("loginRpc err: %v", err) | 41 | logger.Error("loginRpc err: %v", err) |
42 | return 1, nil | 42 | return 1, nil |
43 | } | 43 | } |
@@ -49,7 +49,6 @@ func LoginRpc(msg *net.MsgPkg) (int32, proto.Message) { | @@ -49,7 +49,6 @@ func LoginRpc(msg *net.MsgPkg) (int32, proto.Message) { | ||
49 | role.SetProperty("Device", req.Device) | 49 | role.SetProperty("Device", req.Device) |
50 | 50 | ||
51 | 51 | ||
52 | - msg.Conn.Role = role | ||
53 | return 0, &pb.RoleRsp{ | 52 | return 0, &pb.RoleRsp{ |
54 | Role: role.Role, | 53 | Role: role.Role, |
55 | Hero: role.GetAllHero(), | 54 | Hero: role.GetAllHero(), |
src/plugin/protocode.go renamed to plugin/protocode.go
1 | package plugin | 1 | package plugin |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | + "pro2d/common/components" | ||
4 | "pro2d/pb" | 5 | "pro2d/pb" |
5 | - "pro2d/src/components/logger" | ||
6 | - "pro2d/src/components/net" | 6 | + "pro2d/utils/logger" |
7 | ) | 7 | ) |
8 | 8 | ||
9 | func init() { | 9 | func init() { |
10 | logger.Debug("init protocode...") | 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,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 | \ No newline at end of file | 0 | \ No newline at end of file |
src/components/net/msg.go deleted
@@ -1,57 +0,0 @@ | @@ -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 | \ No newline at end of file | 0 | \ No newline at end of file |
src/components/net/server.go deleted
@@ -1,131 +0,0 @@ | @@ -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 | \ No newline at end of file | 0 | \ No newline at end of file |
src/components/db/mongo.go renamed to utils/db/mongo.go
@@ -8,7 +8,7 @@ import ( | @@ -8,7 +8,7 @@ import ( | ||
8 | "go.mongodb.org/mongo-driver/mongo/options" | 8 | "go.mongodb.org/mongo-driver/mongo/options" |
9 | "go.mongodb.org/mongo-driver/mongo/readpref" | 9 | "go.mongodb.org/mongo-driver/mongo/readpref" |
10 | "go.mongodb.org/mongo-driver/x/bsonx" | 10 | "go.mongodb.org/mongo-driver/x/bsonx" |
11 | - "pro2d/src/utils" | 11 | + "pro2d/utils" |
12 | "sort" | 12 | "sort" |
13 | "strconv" | 13 | "strconv" |
14 | "strings" | 14 | "strings" |
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
@@ -6,7 +6,7 @@ import ( | @@ -6,7 +6,7 @@ import ( | ||
6 | "go.etcd.io/etcd/api/v3/mvccpb" | 6 | "go.etcd.io/etcd/api/v3/mvccpb" |
7 | clientv3 "go.etcd.io/etcd/client/v3" | 7 | clientv3 "go.etcd.io/etcd/client/v3" |
8 | "pro2d/conf" | 8 | "pro2d/conf" |
9 | - "pro2d/src/components/logger" | 9 | + "pro2d/utils/logger" |
10 | "testing" | 10 | "testing" |
11 | ) | 11 | ) |
12 | 12 |
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