Commit 765431a462c47308a5fc53e377699afdacc51c2b
1 parent
77f5eec7
增加schema接口, 抽象 models + db
Showing
38 changed files
with
683 additions
and
632 deletions
Show diff stats
cmd/gameserver/agent.go
... | ... | @@ -5,9 +5,9 @@ import ( |
5 | 5 | "math" |
6 | 6 | "pro2d/common" |
7 | 7 | "pro2d/common/components" |
8 | + "pro2d/common/logger" | |
8 | 9 | "pro2d/models" |
9 | 10 | "pro2d/utils" |
10 | - "pro2d/utils/logger" | |
11 | 11 | "sync/atomic" |
12 | 12 | ) |
13 | 13 | |
... | ... | @@ -43,7 +43,7 @@ func (c *Agent) OnConnection(conn components.IConnection) { |
43 | 43 | |
44 | 44 | func (c *Agent) OnMessage(msg components.IMessage) { |
45 | 45 | atomic.StoreInt64(&c.lastHeartCheckTime, utils.Timex()) |
46 | - md := c.Server.GetPlugin().GetAction(msg.GetHeader().GetMsgID()) | |
46 | + md := c.Server.GetAction(msg.GetHeader().GetMsgID()) | |
47 | 47 | if md == nil { |
48 | 48 | logger.Debug("cmd: %d, md is nil", msg.GetHeader().GetMsgID()) |
49 | 49 | return |
... | ... | @@ -52,17 +52,17 @@ func (c *Agent) OnMessage(msg components.IMessage) { |
52 | 52 | logger.Debug("protocode handler: %d", msg.GetHeader().GetMsgID()) |
53 | 53 | //fmt.Printf("errCode: %d, protomsg:%v\n", errCode, protomsg) |
54 | 54 | |
55 | - f := md.(func (conn components.IConnection, msg components.IMessage) (int32, interface{})) | |
56 | - errCode, protomsg := f(c, msg) | |
55 | + f := md.(func (msg components.IMessage) (int32, interface{})) | |
56 | + errCode, protomsg := f(msg) | |
57 | 57 | rsp, err := proto.Marshal(protomsg.(proto.Message)) |
58 | 58 | if err != nil { |
59 | - conn := c.Server.GetIConnection(msg.GetSessId()) | |
59 | + conn := msg.GetSession() | |
60 | 60 | if conn != nil { |
61 | 61 | conn.Send(-100, msg.GetHeader().GetMsgID(), nil) |
62 | 62 | } |
63 | 63 | return |
64 | 64 | } |
65 | - conn := c.Server.GetIConnection(msg.GetSessId()) | |
65 | + conn := msg.GetSession() | |
66 | 66 | if conn != nil { |
67 | 67 | conn.Send(errCode, msg.GetHeader().GetMsgID(), rsp) |
68 | 68 | } | ... | ... |
cmd/gameserver/game.go
1 | 1 | package main |
2 | 2 | |
3 | 3 | import ( |
4 | - "context" | |
5 | 4 | "fmt" |
6 | - "net/http" | |
7 | 5 | _ "net/http/pprof" |
8 | - "os" | |
9 | - "os/signal" | |
6 | + "pro2d/common" | |
10 | 7 | "pro2d/common/components" |
11 | - "pro2d/conf" | |
8 | + "pro2d/common/db" | |
12 | 9 | "pro2d/models" |
13 | - //_ "pro2d/cmd/gameserver/plugin" | |
14 | - "pro2d/utils/db" | |
15 | - "pro2d/utils/etcd" | |
16 | - "pro2d/utils/logger" | |
10 | + | |
11 | + "pro2d/common/etcd" | |
17 | 12 | "sync" |
18 | - "syscall" | |
19 | 13 | ) |
20 | 14 | |
21 | 15 | type GameServer struct { |
... | ... | @@ -25,12 +19,12 @@ type GameServer struct { |
25 | 19 | Agents *sync.Map |
26 | 20 | } |
27 | 21 | |
28 | -func NewGameServer(sconf *conf.SConf) (*GameServer, error) { | |
22 | +func NewGameServer(sconf *common.SConf) (*GameServer, error) { | |
29 | 23 | s := &GameServer{ |
30 | 24 | Agents: new(sync.Map), |
31 | 25 | } |
32 | 26 | |
33 | - options := []components.Option{ | |
27 | + options := []components.ServerOption{ | |
34 | 28 | components.WithPlugin(components.NewPlugin(sconf.PluginPath)), |
35 | 29 | components.WithSplitter(components.NewPBSplitter()), |
36 | 30 | components.WithConnCbk(s.OnConnection), |
... | ... | @@ -42,21 +36,34 @@ func NewGameServer(sconf *conf.SConf) (*GameServer, error) { |
42 | 36 | iserver := components.NewServer(sconf.Port, options...) |
43 | 37 | s.IServer = iserver |
44 | 38 | |
45 | - //mongo 初始化 | |
46 | - db.MongoDatabase = db.MongoClient.Database(sconf.DBName) | |
47 | - models.InitGameServerModels() | |
39 | + //mgo init | |
40 | + err := db.ConnectMongo(sconf.MongoConf) | |
41 | + if err != nil { | |
42 | + return nil, err | |
43 | + } | |
44 | + models.InitModels() | |
48 | 45 | |
49 | 46 | //Etcd 初始化 |
50 | - var err error | |
51 | - s.EtcdClient, err = etcd.NewEtcdClient(conf.GlobalConf.Etcd) | |
47 | + s.EtcdClient, err = etcd.NewEtcdClient(common.GlobalConf.Etcd) | |
52 | 48 | if err != nil { |
53 | 49 | return nil, err |
54 | 50 | } |
55 | - s.EtcdClient.PutWithLeasePrefix(conf.GlobalConf.GameConf.Name, conf.GlobalConf.GameConf.ID, fmt.Sprintf("%s:%d", conf.GlobalConf.GameConf.IP, conf.GlobalConf.GameConf.Port), 5) | |
51 | + s.EtcdClient.PutWithLeasePrefix(common.GlobalConf.GameConf.Name, common.GlobalConf.GameConf.ID, fmt.Sprintf("%s:%d", common.GlobalConf.GameConf.IP, common.GlobalConf.GameConf.Port), 5) | |
56 | 52 | |
57 | 53 | return s, nil |
58 | 54 | } |
59 | 55 | |
56 | +func (s *GameServer) Start() error { | |
57 | + return s.IServer.Start() | |
58 | +} | |
59 | + | |
60 | +func (s *GameServer) Stop() { | |
61 | + s.IServer.Stop() | |
62 | + | |
63 | + db.CloseMongo() | |
64 | + s.EtcdClient.Close() | |
65 | +} | |
66 | + | |
60 | 67 | func (s *GameServer) OnConnection(conn components.IConnection) { |
61 | 68 | agent := NewAgent(s) |
62 | 69 | agent.OnConnection(conn) |
... | ... | @@ -64,7 +71,7 @@ func (s *GameServer) OnConnection(conn components.IConnection) { |
64 | 71 | } |
65 | 72 | |
66 | 73 | func (s *GameServer) OnMessage(msg components.IMessage) { |
67 | - agent, ok := s.Agents.Load(msg.GetSessId()) | |
74 | + agent, ok := s.Agents.Load(msg.GetSession().GetID()) | |
68 | 75 | if !ok { |
69 | 76 | return |
70 | 77 | } |
... | ... | @@ -87,50 +94,3 @@ func (s *GameServer) OnClose(conn components.IConnection) { |
87 | 94 | agent.(*Agent).OnClose() |
88 | 95 | s.Agents.Delete(conn.GetID()) |
89 | 96 | } |
90 | - | |
91 | -func (s *GameServer) Stop() { | |
92 | - s.IServer.Stop() | |
93 | - | |
94 | - db.MongoClient.Disconnect(context.TODO()) | |
95 | -} | |
96 | - | |
97 | - | |
98 | -func main() { | |
99 | - err := make(chan error) | |
100 | - stopChan := make(chan os.Signal) | |
101 | - signal.Notify(stopChan, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL) | |
102 | - | |
103 | - userChan := make(chan os.Signal) | |
104 | - signal.Notify(userChan, syscall.SIGUSR1, syscall.SIGUSR2) | |
105 | - | |
106 | - s,err1 := NewGameServer(conf.GlobalConf.GameConf) | |
107 | - if err1 != nil { | |
108 | - fmt.Errorf(err1.Error()) | |
109 | - return | |
110 | - } | |
111 | - go func() { | |
112 | - err <- http.ListenAndServe("localhost:6061", nil) | |
113 | - }() | |
114 | - | |
115 | - go func() { | |
116 | - err <- s.Start() | |
117 | - }() | |
118 | - | |
119 | - for { | |
120 | - select { | |
121 | - case e := <- err: | |
122 | - logger.Error("game server error: %v", e) | |
123 | - return | |
124 | - case <-stopChan: | |
125 | - s.Stop() | |
126 | - logger.Debug("game stop...") | |
127 | - return | |
128 | - case u := <-userChan: | |
129 | - logger.Debug("userChan .. %v",u.String()) | |
130 | - e := s.IServer.GetPlugin().LoadPlugin() | |
131 | - if e != nil { | |
132 | - logger.Error("err: ", e.Error()) | |
133 | - } | |
134 | - } | |
135 | - } | |
136 | -} | ... | ... |
... | ... | @@ -0,0 +1,51 @@ |
1 | +package main | |
2 | + | |
3 | +import ( | |
4 | + "fmt" | |
5 | + "net/http" | |
6 | + "os" | |
7 | + "os/signal" | |
8 | + "pro2d/common" | |
9 | + "pro2d/common/logger" | |
10 | + "syscall" | |
11 | +) | |
12 | + | |
13 | +func main() { | |
14 | + err := make(chan error) | |
15 | + stopChan := make(chan os.Signal) | |
16 | + signal.Notify(stopChan, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL) | |
17 | + | |
18 | + userChan := make(chan os.Signal) | |
19 | + signal.Notify(userChan, syscall.SIGUSR1, syscall.SIGUSR2) | |
20 | + | |
21 | + s,err1 := NewGameServer(common.GlobalConf.GameConf) | |
22 | + if err1 != nil { | |
23 | + fmt.Errorf(err1.Error()) | |
24 | + return | |
25 | + } | |
26 | + go func() { | |
27 | + err <- http.ListenAndServe(fmt.Sprintf("localhost:%d", common.GlobalConf.GameConf.DebugPort), nil) | |
28 | + }() | |
29 | + | |
30 | + go func() { | |
31 | + err <- s.Start() | |
32 | + }() | |
33 | + | |
34 | + for { | |
35 | + select { | |
36 | + case e := <- err: | |
37 | + logger.Error("game server error: %v", e) | |
38 | + return | |
39 | + case <-stopChan: | |
40 | + logger.Debug("game stop...") | |
41 | + s.Stop() | |
42 | + return | |
43 | + case u := <-userChan: | |
44 | + logger.Debug("userChan .. %v",u.String()) | |
45 | + e := s.IServer.GetPlugin().LoadPlugin() | |
46 | + if e != nil { | |
47 | + logger.Error("err: ", e.Error()) | |
48 | + } | |
49 | + } | |
50 | + } | |
51 | +} | ... | ... |
cmd/gameserver/plugin/RolePlugin.go
... | ... | @@ -2,11 +2,11 @@ package main |
2 | 2 | |
3 | 3 | import ( |
4 | 4 | "github.com/golang/protobuf/proto" |
5 | + "pro2d/common" | |
5 | 6 | "pro2d/common/components" |
6 | - "pro2d/conf" | |
7 | + "pro2d/common/logger" | |
7 | 8 | "pro2d/models" |
8 | 9 | "pro2d/pb" |
9 | - "pro2d/utils/logger" | |
10 | 10 | ) |
11 | 11 | |
12 | 12 | func HeartRpc(msg components.IMessage) (int32, interface{}) { |
... | ... | @@ -25,7 +25,7 @@ func CreateRpc(msg components.IMessage) (int32, interface{}) { |
25 | 25 | return 2, nil |
26 | 26 | } |
27 | 27 | |
28 | - roleId := conf.SnowFlack.NextValStr() | |
28 | + roleId := common.SnowFlack.NextValStr() | |
29 | 29 | role = models.NewRole(roleId) |
30 | 30 | if err := role.Create(); err != nil { |
31 | 31 | logger.Error("CreateRpc role create err: %v", err) | ... | ... |
cmd/gameserver/plugin/protocode.go
cmd/httpserver/AccountAction.go
... | ... | @@ -2,7 +2,7 @@ package main |
2 | 2 | |
3 | 3 | import ( |
4 | 4 | "github.com/gin-gonic/gin" |
5 | - "pro2d/conf" | |
5 | + "pro2d/common" | |
6 | 6 | "pro2d/models" |
7 | 7 | "pro2d/pb" |
8 | 8 | "pro2d/utils" |
... | ... | @@ -23,7 +23,7 @@ func (h *AccountAction) Register(c *gin.Context) (int, interface{}){ |
23 | 23 | return -2 , "account exists: " + register.Phone |
24 | 24 | } |
25 | 25 | |
26 | - account.Uid = conf.SnowFlack.NextValStr() | |
26 | + account.Uid = common.SnowFlack.NextValStr() | |
27 | 27 | account.Password = utils.Md5V(register.Password) |
28 | 28 | if err := account.Create(); err != nil{ |
29 | 29 | return -3, "account register err: " + err.Error() |
... | ... | @@ -47,10 +47,10 @@ func (h *AccountAction) Login(c *gin.Context) (int,interface{}) { |
47 | 47 | } |
48 | 48 | |
49 | 49 | var gs []*pb.ServiceInfo |
50 | - for k, v := range h.HttpServer.EtcdClient.GetByPrefix(conf.GlobalConf.GameConf.Name) { | |
50 | + for k, v := range h.HttpServer.EtcdClient.GetByPrefix(common.GlobalConf.GameConf.Name) { | |
51 | 51 | gs = append(gs, &pb.ServiceInfo{ |
52 | 52 | Id: k, |
53 | - Name: conf.GlobalConf.GameConf.Name, | |
53 | + Name: common.GlobalConf.GameConf.Name, | |
54 | 54 | Address: v, |
55 | 55 | }) |
56 | 56 | } | ... | ... |
cmd/httpserver/http.go
... | ... | @@ -4,13 +4,11 @@ import ( |
4 | 4 | "fmt" |
5 | 5 | "os" |
6 | 6 | "os/signal" |
7 | + "pro2d/common" | |
7 | 8 | "pro2d/common/components" |
8 | - "pro2d/conf" | |
9 | - _ "pro2d/conf" | |
10 | - "pro2d/models" | |
11 | - "pro2d/utils/db" | |
12 | - "pro2d/utils/etcd" | |
13 | - "pro2d/utils/logger" | |
9 | + "pro2d/common/db" | |
10 | + "pro2d/common/etcd" | |
11 | + "pro2d/common/logger" | |
14 | 12 | "syscall" |
15 | 13 | ) |
16 | 14 | |
... | ... | @@ -24,17 +22,21 @@ func NewAccountServer(version string, port ...string) *AccountServer { |
24 | 22 | } |
25 | 23 | |
26 | 24 | func (s *AccountServer) Init() error { |
27 | - //mongo 初始化 | |
28 | - db.MongoDatabase = db.MongoClient.Database(conf.GlobalConf.AccountConf.DBName) | |
29 | - models.InitAccountServerModels() | |
25 | + //mgo init | |
26 | + err := db.ConnectMongo(common.GlobalConf.AccountConf.MongoConf) | |
30 | 27 | |
31 | 28 | //Etcd 初始化 |
32 | - var err error | |
33 | - s.EtcdClient, err = etcd.NewEtcdClient(conf.GlobalConf.Etcd) | |
29 | + s.EtcdClient, err = etcd.NewEtcdClient(common.GlobalConf.Etcd) | |
34 | 30 | if err != nil { |
35 | 31 | return err |
36 | 32 | } |
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) | |
33 | + | |
34 | + //Etcd 初始化 | |
35 | + s.EtcdClient, err = etcd.NewEtcdClient(common.GlobalConf.Etcd) | |
36 | + if err != nil { | |
37 | + return err | |
38 | + } | |
39 | + s.EtcdClient.PutWithLeasePrefix(common.GlobalConf.AccountConf.Name, common.GlobalConf.AccountConf.ID, fmt.Sprintf("%s:%d", common.GlobalConf.AccountConf.IP, common.GlobalConf.AccountConf.Port), 5) | |
38 | 40 | return nil |
39 | 41 | } |
40 | 42 | |
... | ... | @@ -51,7 +53,7 @@ func main() { |
51 | 53 | stopChan := make(chan os.Signal) |
52 | 54 | signal.Notify(stopChan, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL) |
53 | 55 | |
54 | - web := NewAccountServer("v1", fmt.Sprintf(":%d", conf.GlobalConf.AccountConf.Port)) | |
56 | + web := NewAccountServer("v1", fmt.Sprintf(":%d", common.GlobalConf.AccountConf.Port)) | |
55 | 57 | web.BindHandler(&AccountAction{HttpServer: web}) |
56 | 58 | go func() { |
57 | 59 | err <- web.Start() | ... | ... |
cmd/test/client.go
common/components/conn.go
... | ... | @@ -5,7 +5,7 @@ import ( |
5 | 5 | "fmt" |
6 | 6 | "net" |
7 | 7 | "pro2d/common" |
8 | - "pro2d/utils/logger" | |
8 | + "pro2d/common/logger" | |
9 | 9 | "sync/atomic" |
10 | 10 | "time" |
11 | 11 | ) |
... | ... | @@ -84,18 +84,16 @@ func (c *Connection) Start() { |
84 | 84 | c.handleTimeOut() |
85 | 85 | } |
86 | 86 | |
87 | -func (c *Connection) Stop() { | |
88 | - logger.Debug("ID: %d close", c.Id) | |
89 | - closed := atomic.LoadUint32(&c.Status) | |
90 | - if closed == 0 { | |
87 | +func (c *Connection) Stop() { | |
88 | + sendTimeout := time.NewTimer(5 * time.Millisecond) | |
89 | + defer sendTimeout.Stop() | |
90 | + // 发送超时 | |
91 | + select { | |
92 | + case <-sendTimeout.C: | |
93 | + return | |
94 | + case c.Quit <- c: | |
91 | 95 | return |
92 | 96 | } |
93 | - atomic.StoreUint32(&c.Status, 0) | |
94 | - | |
95 | - close(c.WBuffer) | |
96 | - close(c.Quit) | |
97 | - c.Conn.Close() | |
98 | - c.closeCallback(c) | |
99 | 97 | } |
100 | 98 | |
101 | 99 | func (c *Connection) Send(errCode int32, cmd uint32, data []byte) error{ |
... | ... | @@ -128,7 +126,7 @@ func (c *Connection) defaultTimerCallback(conn IConnection) { |
128 | 126 | } |
129 | 127 | |
130 | 128 | func (c *Connection) write() { |
131 | - defer c.Stop() | |
129 | + defer c.quitting() | |
132 | 130 | |
133 | 131 | for msg := range c.WBuffer { |
134 | 132 | n, err := c.writer.Write(msg) |
... | ... | @@ -144,7 +142,7 @@ func (c *Connection) write() { |
144 | 142 | } |
145 | 143 | |
146 | 144 | func (c *Connection) read() { |
147 | - defer c.Quitting() | |
145 | + defer c.quitting() | |
148 | 146 | c.scanner.Split(c.Server.GetSplitter().ParseMsg) |
149 | 147 | |
150 | 148 | for c.scanner.Scan() { |
... | ... | @@ -153,7 +151,7 @@ func (c *Connection) read() { |
153 | 151 | return |
154 | 152 | } |
155 | 153 | |
156 | - req.SetSessId(c.Id) | |
154 | + req.SetSession(c) | |
157 | 155 | c.readFunc <- func() { |
158 | 156 | c.messageCallback(req) |
159 | 157 | } |
... | ... | @@ -167,7 +165,7 @@ func (c *Connection) read() { |
167 | 165 | |
168 | 166 | //此设计目的是为了让网络数据与定时器处理都在一条协程里处理。不想加锁。。。 |
169 | 167 | func (c *Connection) listen(){ |
170 | - defer c.Stop() | |
168 | + defer c.quitting() | |
171 | 169 | |
172 | 170 | for { |
173 | 171 | select { |
... | ... | @@ -188,6 +186,16 @@ func (c *Connection) handleTimeOut() { |
188 | 186 | TimeOut(1*time.Second, c.handleTimeOut) |
189 | 187 | } |
190 | 188 | |
191 | -func (c *Connection) Quitting() { | |
192 | - c.Quit <- c | |
189 | +func (c *Connection) quitting() { | |
190 | + closed := atomic.LoadUint32(&c.Status) | |
191 | + if closed == 0 { | |
192 | + return | |
193 | + } | |
194 | + atomic.StoreUint32(&c.Status, 0) | |
195 | + | |
196 | + logger.Debug("ID: %d close", c.Id) | |
197 | + close(c.WBuffer) | |
198 | + close(c.Quit) | |
199 | + c.Conn.Close() | |
200 | + c.closeCallback(c) | |
193 | 201 | } | ... | ... |
common/components/icompontents.go
1 | 1 | package components |
2 | 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 | -type ConnectionCallback func(IConnection) | |
33 | -type CloseCallback func(IConnection) | |
34 | -type MessageCallback func(IMessage) | |
35 | -type TimerCallback func(IConnection) | |
36 | - | |
37 | -//链接 | |
38 | -type IConnection interface { | |
39 | - GetID() int | |
40 | - Start() | |
41 | - Stop() | |
42 | - Send(code int32, cmd uint32, b []byte) error | |
43 | - | |
44 | - SetConnectionCallback(ConnectionCallback) | |
45 | - SetMessageCallback(MessageCallback) | |
46 | - SetCloseCallback(CloseCallback) | |
47 | - SetTimerCallback(TimerCallback) | |
48 | -} | |
49 | - | |
50 | -//server | |
51 | -type IServer interface { | |
52 | - Start() error | |
53 | - Stop() | |
54 | - | |
55 | - GetSplitter() ISplitter | |
56 | - GetIConnection(id int) IConnection | |
57 | - GetPlugin() IPlugin | |
58 | - | |
59 | - SetConnectionCallback(ConnectionCallback) | |
60 | - SetMessageCallback(MessageCallback) | |
61 | - SetCloseCallback(CloseCallback) | |
62 | - SetTimerCallback(TimerCallback) | |
63 | -} | |
64 | - | |
65 | -//httpserver | |
66 | -type IHttp interface { | |
67 | - Start() error | |
68 | - Stop() | |
69 | - BindHandler(interface{}) | |
70 | -} | |
71 | - | |
72 | -type ActionHandler func (conn IConnection, msg IMessage) (int32, interface{}) | |
73 | -//用于热更逻辑的插件接口 | |
74 | -type IPlugin interface { | |
75 | - LoadPlugin() error | |
76 | - GetAction(uint32) interface{} | |
77 | -} | |
78 | 3 | \ No newline at end of file |
4 | +//----------------- | |
5 | +//----net start---- | |
6 | +//----------------- | |
7 | +type ( | |
8 | + //网络包头 | |
9 | + IHead interface { | |
10 | + GetDataLen() uint32 //获取消息数据段长度 | |
11 | + GetMsgID() uint32 //获取消息ID | |
12 | + GetErrCode() int32 //获取消息错误码 | |
13 | + GetPreserve() uint32 //获取预留数据 | |
14 | + } | |
15 | + //网络包 | |
16 | + IMessage interface { | |
17 | + IHead | |
18 | + GetHeader() IHead //获取消息头 | |
19 | + SetHeader(header IHead) //设置消息头 | |
20 | + | |
21 | + GetData() []byte //获取消息内容 | |
22 | + SetData([]byte) //设置消息内容 | |
23 | + | |
24 | + SetSession(IConnection) //设置连接 | |
25 | + GetSession() IConnection //获取连接 | |
26 | + } | |
27 | + //网络拆包解包器 | |
28 | + ISplitter interface { | |
29 | + UnPack([]byte) (IMessage, error) | |
30 | + Pack(cmd uint32, data []byte, errcode int32, preserve uint32) ([]byte, error) | |
31 | + ParseMsg(data []byte, atEOF bool) (advance int, token []byte, err error) | |
32 | + GetHeadLen() uint32 | |
33 | + } | |
34 | + ConnectionCallback func(IConnection) | |
35 | + CloseCallback func(IConnection) | |
36 | + MessageCallback func(IMessage) | |
37 | + TimerCallback func(IConnection) | |
38 | + //链接 | |
39 | + IConnection interface { | |
40 | + GetID() int | |
41 | + Start() | |
42 | + Stop() | |
43 | + Send(code int32, cmd uint32, b []byte) error | |
44 | + | |
45 | + SetConnectionCallback(ConnectionCallback) | |
46 | + SetMessageCallback(MessageCallback) | |
47 | + SetCloseCallback(CloseCallback) | |
48 | + SetTimerCallback(TimerCallback) | |
49 | + } | |
50 | + //server | |
51 | + IServer interface { | |
52 | + Start() error | |
53 | + Stop() | |
54 | + | |
55 | + GetSplitter() ISplitter | |
56 | + GetIConnection(id int) IConnection | |
57 | + GetPlugin() IPlugin | |
58 | + GetAction(uint32) interface{} | |
59 | + | |
60 | + SetConnectionCallback(ConnectionCallback) | |
61 | + SetMessageCallback(MessageCallback) | |
62 | + SetCloseCallback(CloseCallback) | |
63 | + SetTimerCallback(TimerCallback) | |
64 | + } | |
65 | + | |
66 | + //httpserver | |
67 | + IHttp interface { | |
68 | + Start() error | |
69 | + Stop() | |
70 | + BindHandler(interface{}) | |
71 | + } | |
72 | + ActionHandler func(conn IConnection, msg IMessage) (int32, interface{}) | |
73 | + //用于热更逻辑的插件接口 | |
74 | + IPlugin interface { | |
75 | + LoadPlugin() error | |
76 | + SetActions(map[interface{}]interface{}) | |
77 | + GetAction(uint32) interface{} | |
78 | + } | |
79 | + | |
80 | + | |
81 | +) | |
82 | + | |
83 | +//----------------- | |
84 | +//-----db start---- | |
85 | +//----------------- | |
86 | +type ( | |
87 | + IDB interface { | |
88 | + CreateTable() error | |
89 | + | |
90 | + Create() (interface{}, error) | |
91 | + Load() error | |
92 | + FindOne() error | |
93 | + UpdateProperty(key string, val interface{}) error | |
94 | + UpdateProperties(properties map[string]interface{}) error | |
95 | + | |
96 | + SetUnique(key string) (string, error) | |
97 | + } | |
98 | + | |
99 | + ISchema interface { | |
100 | + Init() | |
101 | + GetDB() IDB | |
102 | + | |
103 | + GetPri() interface{} | |
104 | + GetSchema() interface{} | |
105 | + GetSchemaName() string | |
106 | + | |
107 | + Load() error | |
108 | + Create() error | |
109 | + Update() | |
110 | + | |
111 | + SetProperty(key string, val interface{}) | |
112 | + SetProperties(properties map[string]interface{}) | |
113 | + } | |
114 | +) | |
115 | + | |
116 | +//----------------- | |
117 | +//-----db end------ | |
118 | +//----------------- | ... | ... |
common/components/pbsplitter.go
... | ... | @@ -35,7 +35,7 @@ type PBMessage struct { |
35 | 35 | Head IHead |
36 | 36 | Body []byte |
37 | 37 | |
38 | - SessionID int | |
38 | + conn IConnection | |
39 | 39 | } |
40 | 40 | |
41 | 41 | |
... | ... | @@ -54,12 +54,12 @@ func (m *PBMessage) SetData(b []byte) { |
54 | 54 | m.Body = b |
55 | 55 | } |
56 | 56 | |
57 | -func (m *PBMessage) SetSessId(id int) { | |
58 | - m.SessionID = id | |
57 | +func (m *PBMessage) SetSession(connection IConnection) { | |
58 | + m.conn = connection | |
59 | 59 | } |
60 | 60 | |
61 | -func (m *PBMessage) GetSessId() int { | |
62 | - return m.SessionID | |
61 | +func (m *PBMessage) GetSession() IConnection { | |
62 | + return m.conn | |
63 | 63 | } |
64 | 64 | |
65 | 65 | ... | ... |
common/components/plugin.go
... | ... | @@ -2,8 +2,8 @@ package components |
2 | 2 | |
3 | 3 | import ( |
4 | 4 | "plugin" |
5 | + "pro2d/common/logger" | |
5 | 6 | "pro2d/pb" |
6 | - "pro2d/utils/logger" | |
7 | 7 | "sync" |
8 | 8 | ) |
9 | 9 | |
... | ... | @@ -43,11 +43,7 @@ func (p *Plugin) LoadPlugin() error { |
43 | 43 | |
44 | 44 | if x, ok := f.(func()map[interface{}]interface{}); ok { |
45 | 45 | logger.Debug("func LoadPlugin GetActionMap success...") |
46 | - am := x() | |
47 | - for k, v := range am { | |
48 | - p.Actions.Delete(k) | |
49 | - p.Actions.Store(k, v) | |
50 | - } | |
46 | + p.SetActions(x()) | |
51 | 47 | } |
52 | 48 | |
53 | 49 | return nil |
... | ... | @@ -60,3 +56,11 @@ func (p *Plugin) GetAction(cmd uint32) interface{} { |
60 | 56 | } |
61 | 57 | return f |
62 | 58 | } |
59 | + | |
60 | +func (p *Plugin) SetActions(am map[interface{}]interface{}) { | |
61 | + for k, v := range am { | |
62 | + cmd := k.(pb.ProtoCode) | |
63 | + p.Actions.Delete(cmd) | |
64 | + p.Actions.Store(cmd, v) | |
65 | + } | |
66 | +} | ... | ... |
common/components/server.go
... | ... | @@ -3,43 +3,43 @@ package components |
3 | 3 | import ( |
4 | 4 | "fmt" |
5 | 5 | "net" |
6 | - "pro2d/utils/logger" | |
6 | + "pro2d/common/logger" | |
7 | 7 | "sync" |
8 | 8 | ) |
9 | 9 | |
10 | -type Option func(*Server) | |
10 | +type ServerOption func(*Server) | |
11 | 11 | |
12 | -func WithPlugin(iPlugin IPlugin) Option { | |
12 | +func WithPlugin(iPlugin IPlugin) ServerOption { | |
13 | 13 | return func(server *Server) { |
14 | 14 | server.plugins = iPlugin |
15 | 15 | } |
16 | 16 | } |
17 | 17 | |
18 | -func WithSplitter(splitter ISplitter) Option { | |
18 | +func WithSplitter(splitter ISplitter) ServerOption { | |
19 | 19 | return func(server *Server) { |
20 | 20 | server.splitter = splitter |
21 | 21 | } |
22 | 22 | } |
23 | 23 | |
24 | -func WithConnCbk(cb ConnectionCallback) Option { | |
24 | +func WithConnCbk(cb ConnectionCallback) ServerOption { | |
25 | 25 | return func(server *Server) { |
26 | 26 | server.connectionCallback = cb |
27 | 27 | } |
28 | 28 | } |
29 | 29 | |
30 | -func WithMsgCbk(cb MessageCallback) Option { | |
30 | +func WithMsgCbk(cb MessageCallback) ServerOption { | |
31 | 31 | return func(server *Server) { |
32 | 32 | server.messageCallback = cb |
33 | 33 | } |
34 | 34 | } |
35 | 35 | |
36 | -func WithCloseCbk(cb CloseCallback) Option { | |
36 | +func WithCloseCbk(cb CloseCallback) ServerOption { | |
37 | 37 | return func(server *Server) { |
38 | 38 | server.closeCallback = cb |
39 | 39 | } |
40 | 40 | } |
41 | 41 | |
42 | -func WithTimerCbk(cb TimerCallback) Option { | |
42 | +func WithTimerCbk(cb TimerCallback) ServerOption { | |
43 | 43 | return func(server *Server) { |
44 | 44 | server.timerCallback = cb |
45 | 45 | } |
... | ... | @@ -50,7 +50,6 @@ type Server struct { |
50 | 50 | PluginPath string |
51 | 51 | plugins IPlugin |
52 | 52 | splitter ISplitter |
53 | - actionHandlers sync.Map | |
54 | 53 | |
55 | 54 | connectionCallback ConnectionCallback |
56 | 55 | messageCallback MessageCallback |
... | ... | @@ -61,7 +60,7 @@ type Server struct { |
61 | 60 | Clients *sync.Map |
62 | 61 | } |
63 | 62 | |
64 | -func NewServer(port int, options ...Option) IServer { | |
63 | +func NewServer(port int, options ...ServerOption) IServer { | |
65 | 64 | s := &Server{ |
66 | 65 | port: port, |
67 | 66 | Clients: new(sync.Map), |
... | ... | @@ -89,6 +88,10 @@ func (s *Server) GetPlugin() IPlugin { |
89 | 88 | return s.plugins |
90 | 89 | } |
91 | 90 | |
91 | +func (s *Server) GetAction(cmd uint32) interface{} { | |
92 | + return s.plugins.GetAction(cmd) | |
93 | +} | |
94 | + | |
92 | 95 | func (s *Server) SetConnectionCallback(cb ConnectionCallback) { |
93 | 96 | s.connectionCallback = cb |
94 | 97 | } |
... | ... | @@ -105,22 +108,6 @@ func (s *Server) SetTimerCallback(cb TimerCallback) { |
105 | 108 | s.timerCallback = cb |
106 | 109 | } |
107 | 110 | |
108 | -func (s *Server) newConnection(conn IConnection) { | |
109 | - s.Clients.Store(conn.GetID(), conn) | |
110 | - | |
111 | - conn.SetConnectionCallback(s.connectionCallback) | |
112 | - conn.SetCloseCallback(s.removeConnection) | |
113 | - conn.SetMessageCallback(s.messageCallback) | |
114 | - conn.SetTimerCallback(s.timerCallback) | |
115 | - | |
116 | - go conn.Start() | |
117 | -} | |
118 | - | |
119 | -func (s *Server) removeConnection(conn IConnection) { | |
120 | - s.closeCallback(conn) | |
121 | - s.Clients.Delete(conn.GetID()) | |
122 | -} | |
123 | - | |
124 | 111 | func (s *Server) Start() error { |
125 | 112 | if err := s.plugins.LoadPlugin(); err != nil { |
126 | 113 | return err |
... | ... | @@ -148,9 +135,26 @@ func (s *Server) Start() error { |
148 | 135 | |
149 | 136 | func (s *Server)Stop() { |
150 | 137 | StopTimer() |
138 | + | |
151 | 139 | s.Clients.Range(func(key, value interface{}) bool { |
152 | 140 | client := value.(IConnection) |
153 | 141 | client.Stop() |
154 | 142 | return true |
155 | 143 | }) |
156 | 144 | } |
145 | + | |
146 | +func (s *Server) newConnection(conn IConnection) { | |
147 | + s.Clients.Store(conn.GetID(), conn) | |
148 | + | |
149 | + conn.SetConnectionCallback(s.connectionCallback) | |
150 | + conn.SetCloseCallback(s.removeConnection) | |
151 | + conn.SetMessageCallback(s.messageCallback) | |
152 | + conn.SetTimerCallback(s.timerCallback) | |
153 | + | |
154 | + go conn.Start() | |
155 | +} | |
156 | + | |
157 | +func (s *Server) removeConnection(conn IConnection) { | |
158 | + s.closeCallback(conn) | |
159 | + s.Clients.Delete(conn.GetID()) | |
160 | +} | ... | ... |
conf/conf.go renamed to common/conf.go
1 | -package conf | |
1 | +package common | |
2 | 2 | |
3 | 3 | import ( |
4 | 4 | "encoding/json" |
5 | 5 | "fmt" |
6 | 6 | "gopkg.in/yaml.v3" |
7 | 7 | "io/ioutil" |
8 | - "pro2d/utils" | |
9 | - "pro2d/utils/db" | |
10 | - "pro2d/utils/logger" | |
8 | + "pro2d/common/logger" | |
11 | 9 | "strings" |
12 | 10 | ) |
13 | 11 | |
... | ... | @@ -29,6 +27,7 @@ type MongoConf struct { |
29 | 27 | Port int `yaml:"port"` |
30 | 28 | TimeOut int `yaml:"timeout"` |
31 | 29 | MaxNum int `yaml:"maxnum"` |
30 | + DBName string `yaml:"dbname"` | |
32 | 31 | } |
33 | 32 | |
34 | 33 | type SConf struct { |
... | ... | @@ -36,7 +35,8 @@ type SConf struct { |
36 | 35 | Name string `yaml:"name"` |
37 | 36 | IP string `yaml:"ip"` |
38 | 37 | Port int `yaml:"port"` |
39 | - DBName string `yaml:"dbname"` | |
38 | + DebugPort int `yaml:"debugport"` | |
39 | + MongoConf *MongoConf `yaml:"mongo"` | |
40 | 40 | WorkerPoolSize int `yaml:"pool_size"` |
41 | 41 | PluginPath string `yaml:"plugin_path"` |
42 | 42 | } |
... | ... | @@ -65,28 +65,27 @@ type LogConn struct { |
65 | 65 | } |
66 | 66 | |
67 | 67 | type LogConf struct { |
68 | - TimeFormat string `yaml:"TimeFormat" json:"TimeFormat"` | |
69 | - LogConsole *LogConsole `yaml:"Console" json:"Console"` | |
70 | - LogFile *LogFile `yaml:"File" json:"File"` | |
71 | - LogConn *LogConn `yaml:"Conn" json:"Conn"` | |
68 | + TimeFormat string `yaml:"TimeFormat" json:"TimeFormat"` | |
69 | + LogConsole *LogConsole `yaml:"Console" json:"Console"` | |
70 | + LogFile *LogFile `yaml:"File" json:"File"` | |
71 | + LogConn *LogConn `yaml:"Conn" json:"Conn"` | |
72 | 72 | } |
73 | 73 | |
74 | 74 | type ServerConf struct { |
75 | - ID string `yaml:"id"` | |
76 | - Name string `yaml:"name"` | |
77 | - WorkerID int64 `yaml:"workerid"` | |
78 | - DatacenterID int64 `yaml:"datacenterid"` | |
79 | - MongoConf *MongoConf `yaml:"mongo"` | |
80 | - AccountConf *SConf `yaml:"server_account"` | |
81 | - GameConf *SConf `yaml:"server_game"` | |
75 | + ID string `yaml:"id"` | |
76 | + Name string `yaml:"name"` | |
77 | + WorkerID int64 `yaml:"workerid"` | |
78 | + DatacenterID int64 `yaml:"datacenterid"` | |
79 | + AccountConf *SConf `yaml:"server_account"` | |
80 | + GameConf *SConf `yaml:"server_game"` | |
82 | 81 | RedisConf *RedisConf `yaml:"redis"` |
83 | - LogConf *LogConf `yaml:"logconf" json:"logconf"` | |
84 | - Etcd *Etcd `yaml:"etcd"` | |
82 | + LogConf *LogConf `yaml:"logconf" json:"logconf"` | |
83 | + Etcd *Etcd `yaml:"etcd"` | |
85 | 84 | } |
86 | 85 | |
87 | 86 | var( |
88 | 87 | GlobalConf ServerConf |
89 | - SnowFlack *utils.Snowflake | |
88 | + SnowFlack *Snowflake | |
90 | 89 | ) |
91 | 90 | |
92 | 91 | func init() { |
... | ... | @@ -114,11 +113,5 @@ func init() { |
114 | 113 | } |
115 | 114 | |
116 | 115 | //初始化雪花算法 |
117 | - SnowFlack = utils.NewSnowflake(GlobalConf.WorkerID, GlobalConf.DatacenterID) | |
118 | - | |
119 | - err = db.Connect(GlobalConf.MongoConf.User, GlobalConf.MongoConf.Password, GlobalConf.MongoConf.Host, GlobalConf.MongoConf.Port, GlobalConf.MongoConf.MaxNum, GlobalConf.MongoConf.TimeOut) | |
120 | - if err != nil { | |
121 | - logger.Error("connect db err: %v", err) | |
122 | - } | |
123 | - | |
116 | + SnowFlack = NewSnowflake(GlobalConf.WorkerID, GlobalConf.DatacenterID) | |
124 | 117 | } |
125 | 118 | \ No newline at end of file | ... | ... |
... | ... | @@ -0,0 +1,104 @@ |
1 | +package db | |
2 | + | |
3 | +import ( | |
4 | + "context" | |
5 | + "fmt" | |
6 | + "go.mongodb.org/mongo-driver/bson" | |
7 | + "go.mongodb.org/mongo-driver/mongo" | |
8 | + "go.mongodb.org/mongo-driver/mongo/options" | |
9 | + "go.mongodb.org/mongo-driver/x/bsonx" | |
10 | + "pro2d/common/components" | |
11 | + "sort" | |
12 | + "strings" | |
13 | +) | |
14 | + | |
15 | +var ( | |
16 | + mongoClient *mongo.Client | |
17 | + mongoDatabase *mongo.Database | |
18 | +) | |
19 | + | |
20 | +type MgoColl struct { | |
21 | + components.IDB | |
22 | + Schema components.ISchema | |
23 | + | |
24 | + dbname string | |
25 | + coll *mongo.Collection | |
26 | +} | |
27 | + | |
28 | +func NewMongoColl(dbname string, schema components.ISchema) *MgoColl { | |
29 | + m := &MgoColl{ | |
30 | + dbname: dbname, | |
31 | + coll: DB().Collection(dbname), | |
32 | + Schema: schema, | |
33 | + } | |
34 | + return m | |
35 | +} | |
36 | + | |
37 | +func (m *MgoColl) CreateTable() error { | |
38 | + colls, _ := DB().ListCollectionNames(context.TODO(), bson.D{}) | |
39 | + pos := sort.SearchStrings(colls, m.dbname) | |
40 | + if pos != len(colls) { | |
41 | + if m.dbname == colls[pos] { | |
42 | + return DB().CreateCollection(context.TODO(), m.dbname) | |
43 | + } | |
44 | + } | |
45 | + return DB().CreateCollection(context.TODO(), m.dbname) | |
46 | +} | |
47 | + | |
48 | +func (m *MgoColl) Create() (interface{}, error){ | |
49 | + return m.coll.InsertOne(context.TODO(), m.Schema.GetSchema()) | |
50 | +} | |
51 | + | |
52 | +func (m *MgoColl) Load() error{ | |
53 | + r := m.coll.FindOne(context.TODO(), m.Schema.GetPri()) | |
54 | + err := r.Decode(m.Schema.GetSchema()) | |
55 | + if err != nil { | |
56 | + return err | |
57 | + } | |
58 | + return nil | |
59 | +} | |
60 | + | |
61 | +// 查询单个 | |
62 | +func (m *MgoColl) FindOne() error { | |
63 | + singleResult := m.coll.FindOne(context.TODO(), m.Schema.GetPri()) | |
64 | + return singleResult.Decode(m.Schema.GetSchema()) | |
65 | +} | |
66 | + | |
67 | +func (m *MgoColl) UpdateOne(filter interface{}, update interface{})*mongo.UpdateResult { | |
68 | + res, err := m.coll.UpdateOne(context.TODO(), filter, bson.D{{"$set", update}}) | |
69 | + if err != nil { | |
70 | + return nil | |
71 | + } | |
72 | + return res | |
73 | +} | |
74 | + | |
75 | +func (m *MgoColl) UpdateProperty(key string, val interface{}) error { | |
76 | + _, err := m.coll.UpdateOne(context.TODO(), m.Schema.GetPri(), bson.D{{"$set", bson.M{strings.ToLower(key): val}}}) | |
77 | + return err | |
78 | +} | |
79 | + | |
80 | +func (m *MgoColl) UpdateProperties(properties map[string]interface{}) error { | |
81 | + _, err := m.coll.UpdateOne(context.TODO(), m.Schema.GetPri(), properties) | |
82 | + return err | |
83 | +} | |
84 | + | |
85 | +//索引 | |
86 | +func (m *MgoColl) SetUnique(key string) (string, error){ | |
87 | + return m.coll.Indexes().CreateOne( | |
88 | + context.Background(), | |
89 | + mongo.IndexModel{ | |
90 | + Keys : bsonx.Doc{{key, bsonx.Int32(1)}}, | |
91 | + Options: options.Index().SetUnique(true), | |
92 | + }, | |
93 | + ) | |
94 | +} | |
95 | + | |
96 | +func (m *MgoColl) Delete(key string, value interface{}) int64 { | |
97 | + filter := bson.D{ {key, value}} | |
98 | + count, err := m.coll.DeleteOne(context.TODO(), filter, nil) | |
99 | + if err != nil { | |
100 | + fmt.Println(err) | |
101 | + } | |
102 | + return count.DeletedCount | |
103 | + | |
104 | +} | ... | ... |
... | ... | @@ -0,0 +1,148 @@ |
1 | +package db | |
2 | + | |
3 | +import ( | |
4 | + "context" | |
5 | + "fmt" | |
6 | + "go.mongodb.org/mongo-driver/bson" | |
7 | + "go.mongodb.org/mongo-driver/mongo" | |
8 | + "go.mongodb.org/mongo-driver/mongo/options" | |
9 | + "go.mongodb.org/mongo-driver/mongo/readpref" | |
10 | + "go.mongodb.org/mongo-driver/x/bsonx" | |
11 | + "pro2d/common" | |
12 | + "pro2d/common/logger" | |
13 | + "reflect" | |
14 | + "sort" | |
15 | + "strings" | |
16 | + "time" | |
17 | +) | |
18 | + | |
19 | +func DB() *mongo.Database { | |
20 | + return mongoDatabase | |
21 | +} | |
22 | + | |
23 | +func ConnectMongo(conf *common.MongoConf) error { | |
24 | + var uri string | |
25 | + if conf.User!= "" { | |
26 | + //uri = fmt.Sprintf("mongodb://%s:%s@%s:%d/%s?w=majority", conf.User, conf.Password, conf.Host, conf.Port, conf.DBName) | |
27 | + uri = fmt.Sprintf("mongodb://%s:%s@%s:%d/?w=majority", conf.User, conf.Password, conf.Host, conf.Port) | |
28 | + }else { | |
29 | + //uri = fmt.Sprintf("mongodb://%s:%d/%s?w=majority", conf.Host, conf.Port, conf.DBName) | |
30 | + uri = fmt.Sprintf("mongodb://%s:%d/?w=majority", conf.Host, conf.Port) | |
31 | + } | |
32 | + // 设置连接超时时间 | |
33 | + ctx, cancel := context.WithTimeout(context.Background(), time.Duration(conf.TimeOut) * time.Second) | |
34 | + defer cancel() | |
35 | + // 通过传进来的uri连接相关的配置 | |
36 | + o := options.Client().ApplyURI(uri) | |
37 | + // 设置最大连接数 - 默认是100 ,不设置就是最大 max 64 | |
38 | + o.SetMaxPoolSize(uint64(conf.MaxNum)) | |
39 | + // 发起链接 | |
40 | + var err error | |
41 | + mongoClient, err = mongo.Connect(ctx, o) | |
42 | + if err != nil { | |
43 | + return err | |
44 | + } | |
45 | + // 判断服务是不是可用 | |
46 | + if err = mongoClient.Ping(context.Background(), readpref.Primary()); err != nil { | |
47 | + return err | |
48 | + } | |
49 | + | |
50 | + mongoDatabase = mongoClient.Database(conf.DBName) | |
51 | + return nil | |
52 | +} | |
53 | + | |
54 | +func CloseMongo(){ | |
55 | + mongoClient.Disconnect(context.TODO()) | |
56 | +} | |
57 | + | |
58 | +func CreateTable(tb string) error { | |
59 | + colls, _ := DB().ListCollectionNames(context.TODO(), bson.D{}) | |
60 | + pos := sort.SearchStrings(colls, tb) | |
61 | + if pos != len(colls) { | |
62 | + if tb == colls[pos] { | |
63 | + return DB().CreateCollection(context.TODO(), tb) | |
64 | + } | |
65 | + } | |
66 | + return DB().CreateCollection(context.TODO(), tb) | |
67 | +} | |
68 | + | |
69 | +func FindOne(pri interface{}, schema interface{}) error { | |
70 | + r := mongoDatabase.Collection(GetCollName(schema)).FindOne(context.TODO(), pri) | |
71 | + return r.Decode(schema) | |
72 | +} | |
73 | + | |
74 | +func GetBsonD(key string, value interface{}) interface{} { | |
75 | + return bson.D{ {key, value}} | |
76 | +} | |
77 | + | |
78 | +func GetBsonM(key string, value interface{}) interface{} { | |
79 | + return bson.M{key: value} | |
80 | +} | |
81 | + | |
82 | +func GetSchemaType(schema interface{}) reflect.Type { | |
83 | + s := reflect.TypeOf(schema) | |
84 | + if s.Kind() == reflect.Ptr { | |
85 | + s = reflect.TypeOf(schema).Elem() | |
86 | + } | |
87 | + return s | |
88 | +} | |
89 | + | |
90 | +func GetCollName(schema interface{}) string { | |
91 | + return strings.ToLower(GetSchemaType(schema).Name()) | |
92 | +} | |
93 | + | |
94 | +func GetPriKey(schema interface{}) string { | |
95 | + s := GetSchemaType(schema) | |
96 | + | |
97 | + var pri string | |
98 | + for i := 0; i < s.NumField(); i++ { | |
99 | + if s.Field(i).Tag.Get("pri") == "1" { | |
100 | + pri = strings.ToLower(s.Field(i).Name) | |
101 | + break | |
102 | + } | |
103 | + } | |
104 | + return pri | |
105 | +} | |
106 | + | |
107 | +func FindIndex(schema interface{}) (string, []string){ | |
108 | + s := GetSchemaType(schema) | |
109 | + | |
110 | + var index []string | |
111 | + for i := 0; i < s.NumField(); i++ { | |
112 | + if s.Field(i).Tag.Get("index") != "" { | |
113 | + js := strings.Split(s.Field(i).Tag.Get("json"), ",") | |
114 | + if len(js) == 0 { | |
115 | + continue | |
116 | + } | |
117 | + index = append(index, js[0]) | |
118 | + } | |
119 | + } | |
120 | + return strings.ToLower(s.Name()), index | |
121 | +} | |
122 | + | |
123 | +func SetUnique(coll, key string) (string, error){ | |
124 | + return DB().Collection(coll).Indexes().CreateOne( | |
125 | + context.TODO(), | |
126 | + mongo.IndexModel{ | |
127 | + Keys : bsonx.Doc{{key, bsonx.Int32(1)}}, | |
128 | + Options: options.Index().SetUnique(true), | |
129 | + }, | |
130 | + ) | |
131 | +} | |
132 | + | |
133 | +func InitDoc(schema ...interface{}) { | |
134 | + for _, s := range schema { | |
135 | + coll, keys := FindIndex(s) | |
136 | + CreateTable(coll) | |
137 | + for _, index := range keys { | |
138 | + | |
139 | + logger.Debug("InitDoc collect: %v, createIndex: %s", coll, index) | |
140 | + res, err := SetUnique(coll, index) | |
141 | + if err != nil { | |
142 | + logger.Error("InitDoc unique: %s, err: %v", res, err) | |
143 | + continue | |
144 | + } | |
145 | + } | |
146 | + } | |
147 | + | |
148 | +} | |
0 | 149 | \ No newline at end of file | ... | ... |
utils/db/redis.go renamed to common/db/redis.go
utils/etcd/etcd.go renamed to common/etcd/etcd.go
... | ... | @@ -4,8 +4,8 @@ import ( |
4 | 4 | "context" |
5 | 5 | "fmt" |
6 | 6 | clientv3 "go.etcd.io/etcd/client/v3" |
7 | - "pro2d/conf" | |
8 | - "pro2d/utils/logger" | |
7 | + "pro2d/common" | |
8 | + "pro2d/common/logger" | |
9 | 9 | "time" |
10 | 10 | ) |
11 | 11 | |
... | ... | @@ -13,7 +13,7 @@ type EtcdClient struct { |
13 | 13 | etcd *clientv3.Client |
14 | 14 | } |
15 | 15 | |
16 | -func NewEtcdClient(conf *conf.Etcd) (*EtcdClient, error) { | |
16 | +func NewEtcdClient(conf *common.Etcd) (*EtcdClient, error) { | |
17 | 17 | cli, err := clientv3.New(clientv3.Config{ |
18 | 18 | Endpoints: conf.Endpoints, |
19 | 19 | DialTimeout: time.Duration(conf.DialTimeout) * time.Second, | ... | ... |
utils/etcd/etcd_test.go renamed to common/etcd/etcd_test.go
... | ... | @@ -5,23 +5,23 @@ import ( |
5 | 5 | "fmt" |
6 | 6 | "go.etcd.io/etcd/api/v3/mvccpb" |
7 | 7 | clientv3 "go.etcd.io/etcd/client/v3" |
8 | - "pro2d/conf" | |
9 | - "pro2d/utils/logger" | |
8 | + "pro2d/common" | |
9 | + "pro2d/common/logger" | |
10 | 10 | "testing" |
11 | 11 | ) |
12 | 12 | |
13 | 13 | func TestEtcdClient_GetByPrefix(t *testing.T) { |
14 | - etcd, err := NewEtcdClient(conf.GlobalConf.Etcd) | |
14 | + etcd, err := NewEtcdClient(common.GlobalConf.Etcd) | |
15 | 15 | if err != nil { |
16 | 16 | logger.Error(err) |
17 | 17 | return |
18 | 18 | } |
19 | - gameInfo := etcd.GetByPrefix(conf.GlobalConf.AccountConf.Name) | |
19 | + gameInfo := etcd.GetByPrefix(common.GlobalConf.AccountConf.Name) | |
20 | 20 | for k, v := range gameInfo { |
21 | 21 | logger.Debug("game info key: %v val: %v", k, v) |
22 | 22 | } |
23 | 23 | |
24 | - rch := etcd.etcd.Watch(context.Background(), fmt.Sprintf("/%s/", conf.GlobalConf.AccountConf.Name), clientv3.WithPrefix()) | |
24 | + rch := etcd.etcd.Watch(context.Background(), fmt.Sprintf("/%s/", common.GlobalConf.AccountConf.Name), clientv3.WithPrefix()) | |
25 | 25 | go func() { |
26 | 26 | for wresp := range rch { |
27 | 27 | for _, ev := range wresp.Events { |
... | ... | @@ -35,7 +35,7 @@ func TestEtcdClient_GetByPrefix(t *testing.T) { |
35 | 35 | } |
36 | 36 | }() |
37 | 37 | |
38 | - game := etcd.etcd.Watch(context.Background(), fmt.Sprintf("/%s/", conf.GlobalConf.GameConf.Name), clientv3.WithPrefix()) | |
38 | + game := etcd.etcd.Watch(context.Background(), fmt.Sprintf("/%s/", common.GlobalConf.GameConf.Name), clientv3.WithPrefix()) | |
39 | 39 | for wresp := range game { |
40 | 40 | for _, ev := range wresp.Events { |
41 | 41 | switch ev.Type { | ... | ... |
utils/logger/README.md renamed to common/logger/README.md
utils/logger/conn.go renamed to common/logger/conn.go
utils/logger/console.go renamed to common/logger/console.go
utils/logger/file.go renamed to common/logger/file.go
utils/logger/log.go renamed to common/logger/log.go
utils/snowflake.go renamed to common/snowflake.go
conf/conf.yaml
... | ... | @@ -21,17 +21,22 @@ server_account: |
21 | 21 | name: "account" |
22 | 22 | ip: "192.168.0.206" |
23 | 23 | port: 8858 |
24 | - dbname: "account" | |
25 | 24 | pool_size: 1 |
25 | + debugport: 6061 | |
26 | + mongo: | |
27 | + <<: *default-mongo | |
28 | + dbname: "account" | |
26 | 29 | |
27 | 30 | server_game: |
28 | 31 | id: "1" |
29 | 32 | name: "game" |
30 | 33 | ip: "192.168.0.206" |
31 | 34 | port: 8850 |
32 | - dbname: "game" | |
33 | 35 | pool_size: 1 |
34 | 36 | plugin_path: "./bin/plugin.so" |
37 | + mongo: | |
38 | + <<: *default-mongo | |
39 | + dbname: "game" | |
35 | 40 | |
36 | 41 | logconf: |
37 | 42 | TimeFormat: "2006-01-02 15:04:05" | ... | ... |
models/account.go
... | ... | @@ -2,11 +2,10 @@ package models |
2 | 2 | |
3 | 3 | import ( |
4 | 4 | "pro2d/pb" |
5 | - "pro2d/utils/db" | |
6 | 5 | ) |
7 | 6 | |
8 | 7 | type AccountModel struct { |
9 | - *db.Schema | |
8 | + *Schema | |
10 | 9 | *pb.Account |
11 | 10 | } |
12 | 11 | |
... | ... | @@ -21,9 +20,11 @@ func AccountExistByPhone(phone string) (bool, *AccountModel){ |
21 | 20 | func NewAccount(phone string) *AccountModel { |
22 | 21 | ac := &pb.Account{ |
23 | 22 | Phone: phone, |
23 | + | |
24 | 24 | } |
25 | + | |
25 | 26 | account := &AccountModel{ |
26 | - Schema: db.NewSchema(phone, ac), | |
27 | + Schema: NewSchema(phone, ac), | |
27 | 28 | Account: ac, |
28 | 29 | } |
29 | 30 | ... | ... |
models/equip.go
... | ... | @@ -2,20 +2,19 @@ package models |
2 | 2 | |
3 | 3 | import ( |
4 | 4 | "pro2d/pb" |
5 | - "pro2d/utils/db" | |
6 | 5 | ) |
7 | 6 | |
8 | -type EquipModels struct { | |
9 | - *db.Schema | |
7 | +type EquipModel struct { | |
8 | + *Schema | |
10 | 9 | Equip *pb.Equipment |
11 | 10 | } |
12 | 11 | |
13 | -func NewEquip(id string) *EquipModels { | |
12 | +func NewEquip(id string) *EquipModel { | |
14 | 13 | data := &pb.Equipment{ |
15 | 14 | Id: id, |
16 | 15 | } |
17 | - m := &EquipModels{ | |
18 | - Schema: db.NewSchema(id, data), | |
16 | + m := &EquipModel{ | |
17 | + Schema: NewSchema(id, data), | |
19 | 18 | Equip: data, |
20 | 19 | } |
21 | 20 | ... | ... |
models/hero.go
... | ... | @@ -2,11 +2,10 @@ package models |
2 | 2 | |
3 | 3 | import ( |
4 | 4 | "pro2d/pb" |
5 | - "pro2d/utils/db" | |
6 | 5 | ) |
7 | 6 | |
8 | 7 | type HeroModel struct { |
9 | - *db.Schema | |
8 | + *Schema | |
10 | 9 | Hero *pb.Hero |
11 | 10 | } |
12 | 11 | type HeroMap map[string]*HeroModel |
... | ... | @@ -24,7 +23,7 @@ func NewHero(id string) *HeroModel { |
24 | 23 | Id: id, |
25 | 24 | } |
26 | 25 | m := &HeroModel{ |
27 | - Schema: db.NewSchema(id, h), | |
26 | + Schema: NewSchema(id, h), | |
28 | 27 | Hero: h, |
29 | 28 | } |
30 | 29 | return m | ... | ... |
models/init.go
1 | 1 | package models |
2 | 2 | |
3 | 3 | import ( |
4 | + "pro2d/common/db" | |
4 | 5 | "pro2d/pb" |
5 | - "pro2d/utils" | |
6 | - "pro2d/utils/db" | |
7 | - "pro2d/utils/logger" | |
8 | 6 | ) |
9 | 7 | |
10 | -func InitDoc(schema ...interface{}) { | |
11 | - for _, s := range schema { | |
12 | - coll, keys := utils.FindIndex(s) | |
13 | - for _, index := range keys { | |
14 | - db.CreateCollection(coll) | |
15 | - | |
16 | - logger.Debug("InitDoc collect: %v, createIndex: %s", coll, index) | |
17 | - res, err := db.SetUnique(coll, index) | |
18 | - if err != nil { | |
19 | - logger.Error("InitDoc unique: %s, err: %v", res, err) | |
20 | - continue | |
21 | - } | |
22 | - } | |
23 | - } | |
24 | -} | |
25 | - | |
26 | -func InitAccountServerModels() { | |
8 | +func InitModels() { | |
27 | 9 | var schema []interface{} = []interface{}{ |
28 | 10 | pb.Account{}, |
29 | - } | |
30 | - InitDoc(schema...) | |
31 | -} | |
32 | - | |
33 | -func InitGameServerModels() { | |
34 | - var schema []interface{} = []interface{}{ | |
11 | + pb.Equipment{}, | |
35 | 12 | pb.Hero{}, |
13 | + pb.Prop{}, | |
36 | 14 | pb.Role{}, |
37 | 15 | pb.Team{}, |
38 | 16 | } |
39 | - InitDoc(schema...) | |
40 | -} | |
41 | 17 | \ No newline at end of file |
18 | + db.InitDoc(schema...) | |
19 | +} | ... | ... |
models/init_test.go deleted
... | ... | @@ -1,20 +0,0 @@ |
1 | -package models | |
2 | - | |
3 | -import ( | |
4 | - "context" | |
5 | - _ "pro2d/conf" | |
6 | - "pro2d/utils/db" | |
7 | - "testing" | |
8 | -) | |
9 | - | |
10 | - | |
11 | -func TestInitModels(t *testing.T) { | |
12 | - | |
13 | - db.MongoDatabase = db.MongoClient.Database("account") | |
14 | - InitAccountServerModels() | |
15 | - db.MongoClient.Disconnect(context.TODO()) | |
16 | - | |
17 | - db.MongoDatabase = db.MongoClient.Database("game") | |
18 | - InitGameServerModels() | |
19 | - db.MongoClient.Disconnect(context.TODO()) | |
20 | -} | |
21 | 0 | \ No newline at end of file |
models/prop.go
... | ... | @@ -2,20 +2,19 @@ package models |
2 | 2 | |
3 | 3 | import ( |
4 | 4 | "pro2d/pb" |
5 | - "pro2d/utils/db" | |
6 | 5 | ) |
7 | 6 | |
8 | -type PropModels struct { | |
9 | - *db.Schema | |
7 | +type PropModel struct { | |
8 | + *Schema | |
10 | 9 | Prop *pb.Prop |
11 | 10 | } |
12 | 11 | |
13 | -func NewProp(id string) *PropModels { | |
12 | +func NewProp(id string) *PropModel { | |
14 | 13 | data := &pb.Prop{ |
15 | 14 | Id: id, |
16 | 15 | } |
17 | - m := &PropModels{ | |
18 | - Schema: db.NewSchema(id, data), | |
16 | + m := &PropModel{ | |
17 | + Schema: NewSchema(id, data), | |
19 | 18 | Prop: data, |
20 | 19 | } |
21 | 20 | ... | ... |
models/role.go
... | ... | @@ -3,20 +3,20 @@ package models |
3 | 3 | import ( |
4 | 4 | "fmt" |
5 | 5 | "pro2d/common" |
6 | + "pro2d/common/db" | |
7 | + "pro2d/common/logger" | |
6 | 8 | "pro2d/pb" |
7 | 9 | "pro2d/utils" |
8 | - "pro2d/utils/db" | |
9 | - "pro2d/utils/logger" | |
10 | 10 | "sync/atomic" |
11 | 11 | ) |
12 | 12 | |
13 | 13 | type RoleModel struct { |
14 | - *db.Schema | |
14 | + *Schema | |
15 | 15 | Role *pb.Role |
16 | 16 | Heros HeroMap |
17 | 17 | Teams *TeamModel |
18 | - Equip *EquipModels | |
19 | - Prop *PropModels | |
18 | + Equip *EquipModel | |
19 | + Prop *PropModel | |
20 | 20 | |
21 | 21 | lastSaveTs int64 |
22 | 22 | } |
... | ... | @@ -31,12 +31,12 @@ func RoleExistByUid(uid string) *RoleModel { |
31 | 31 | |
32 | 32 | |
33 | 33 | r := &RoleModel{ |
34 | - Schema: db.NewSchema(data.Id, data), | |
34 | + Schema: NewSchema(data.Id, data), | |
35 | 35 | Role: data, |
36 | 36 | Heros: make(HeroMap), |
37 | 37 | Teams: new(TeamModel), |
38 | - Equip: new(EquipModels), | |
39 | - Prop: new(PropModels), | |
38 | + Equip: new(EquipModel), | |
39 | + Prop: new(PropModel), | |
40 | 40 | } |
41 | 41 | r.LoadAll() |
42 | 42 | return r |
... | ... | @@ -45,12 +45,12 @@ func RoleExistByUid(uid string) *RoleModel { |
45 | 45 | func NewRole(id string) *RoleModel { |
46 | 46 | data := &pb.Role{Id: id} |
47 | 47 | m := &RoleModel{ |
48 | - Schema: db.NewSchema(id, data), | |
48 | + Schema: NewSchema(id, data), | |
49 | 49 | Role: data, |
50 | 50 | Heros: make(HeroMap), |
51 | 51 | Teams: new(TeamModel), |
52 | - Equip: new(EquipModels), | |
53 | - Prop: new(PropModels), | |
52 | + Equip: new(EquipModel), | |
53 | + Prop: new(PropModel), | |
54 | 54 | } |
55 | 55 | return m |
56 | 56 | } | ... | ... |
models/role_test.go
... | ... | @@ -2,16 +2,20 @@ package models |
2 | 2 | |
3 | 3 | import ( |
4 | 4 | "fmt" |
5 | - _ "pro2d/conf" | |
5 | + "pro2d/common" | |
6 | + "pro2d/common/db" | |
7 | + "pro2d/common/logger" | |
6 | 8 | "pro2d/pb" |
7 | 9 | "pro2d/utils" |
8 | - "pro2d/utils/db" | |
9 | - "pro2d/utils/logger" | |
10 | 10 | "testing" |
11 | 11 | ) |
12 | 12 | |
13 | 13 | func TestNewRole(t *testing.T) { |
14 | - db.MongoDatabase = db.MongoClient.Database("game") | |
14 | + err := db.ConnectMongo(common.GlobalConf.MongoConf) | |
15 | + if err != nil { | |
16 | + logger.Error(err) | |
17 | + return | |
18 | + } | |
15 | 19 | |
16 | 20 | var uid = "141815055745814528" |
17 | 21 | role := RoleExistByUid(uid) | ... | ... |
utils/db/schema.go renamed to models/schema.go
1 | -package db | |
1 | +package models | |
2 | 2 | |
3 | 3 | import ( |
4 | + "pro2d/common/components" | |
5 | + "pro2d/common/db" | |
6 | + "pro2d/common/logger" | |
4 | 7 | "reflect" |
5 | 8 | "strings" |
6 | 9 | ) |
7 | 10 | |
11 | +type SchemaOption func(schema *Schema) | |
12 | + | |
13 | +func WithSchemaDB(idb components.IDB) SchemaOption { | |
14 | + return func(schema *Schema) { | |
15 | + schema.db = idb | |
16 | + } | |
17 | +} | |
18 | + | |
8 | 19 | type Schema struct { |
9 | - mgo *MgoColl | |
20 | + db components.IDB | |
10 | 21 | reflectValue *reflect.Value |
11 | 22 | reflectType reflect.Type |
12 | 23 | |
... | ... | @@ -27,28 +38,42 @@ func NewSchema(key string, schema interface{}) *Schema { |
27 | 38 | cacheFields: make(map[string]interface{}), |
28 | 39 | schema: schema, |
29 | 40 | } |
30 | - sch.mgo = NewMongoColl(sch) | |
31 | - sch.pri = GetBsonD(sch.getPriTag(), key) | |
41 | + | |
42 | + sch.db = db.NewMongoColl(sch.GetSchemaName(), sch) | |
43 | + sch.pri = db.GetBsonD(sch.getPriTag(), key) | |
32 | 44 | return sch |
33 | 45 | } |
34 | 46 | |
35 | -func (s *Schema) GetSchemaType() reflect.Type { | |
36 | - return s.reflectType | |
47 | +func (s *Schema) FindIndex() (string, []string) { | |
48 | + var index []string | |
49 | + for i := 0; i < s.reflectType.NumField(); i++ { | |
50 | + if s.reflectType.Field(i).Tag.Get("index") != "" { | |
51 | + js := strings.Split(s.reflectType.Field(i).Tag.Get("json"), ",") | |
52 | + if len(js) == 0 { | |
53 | + continue | |
54 | + } | |
55 | + index = append(index, js[0]) | |
56 | + } | |
57 | + } | |
58 | + return strings.ToLower(s.reflectType.Name()), index | |
37 | 59 | } |
38 | 60 | |
39 | -func (s *Schema) GetCollName() string { | |
40 | - return strings.ToLower(s.GetSchemaType().Name()) | |
41 | -} | |
61 | +func (s *Schema) Init() { | |
62 | + coll, keys := s.FindIndex() | |
63 | + for _, index := range keys { | |
64 | + s.db.CreateTable() | |
42 | 65 | |
43 | -func (s *Schema) getPriTag() string { | |
44 | - var pri string | |
45 | - for i := 0; i < s.reflectType.NumField(); i++ { | |
46 | - if s.reflectType.Field(i).Tag.Get("pri") == "1" { | |
47 | - pri = strings.ToLower(s.reflectType.Field(i).Name) | |
48 | - break | |
66 | + logger.Debug("InitDoc collect: %v, createIndex: %s", coll, index) | |
67 | + res, err := s.db.SetUnique(index) | |
68 | + if err != nil { | |
69 | + logger.Error("InitDoc unique: %s, err: %v", res, err) | |
70 | + continue | |
49 | 71 | } |
50 | 72 | } |
51 | - return pri | |
73 | +} | |
74 | + | |
75 | +func (s *Schema) GetDB() components.IDB { | |
76 | + return s.db | |
52 | 77 | } |
53 | 78 | |
54 | 79 | func (s *Schema) GetPri() interface{} { |
... | ... | @@ -59,18 +84,22 @@ func (s *Schema) GetSchema() interface{} { |
59 | 84 | return s.schema |
60 | 85 | } |
61 | 86 | |
87 | +func (s *Schema) GetSchemaName() string { | |
88 | + return strings.ToLower(s.reflectType.Name()) | |
89 | +} | |
90 | + | |
62 | 91 | func (s *Schema) Load() error { |
63 | - return s.mgo.Load() | |
92 | + return s.db.Load() | |
64 | 93 | } |
65 | 94 | |
66 | 95 | func (s *Schema) Create() error { |
67 | - _, err := s.mgo.Create() | |
96 | + _, err := s.db.Create() | |
68 | 97 | return err |
69 | 98 | } |
70 | 99 | |
71 | 100 | func (s *Schema) Update() { |
72 | 101 | if s.cacheFields != nil { |
73 | - s.mgo.UpdateProperties(s.cacheFields) | |
102 | + s.db.UpdateProperties(s.cacheFields) | |
74 | 103 | s.cacheFields = make(map[string]interface{}) |
75 | 104 | } |
76 | 105 | } |
... | ... | @@ -85,4 +114,15 @@ func (s *Schema) SetProperties(properties map[string]interface{}) { |
85 | 114 | s.reflectValue.FieldByName(key).Set(reflect.ValueOf(val)) |
86 | 115 | s.cacheFields[strings.ToLower(key)] = val |
87 | 116 | } |
88 | -} | |
89 | 117 | \ No newline at end of file |
118 | +} | |
119 | + | |
120 | +func (s *Schema) getPriTag() string { | |
121 | + var pri string | |
122 | + for i := 0; i < s.reflectType.NumField(); i++ { | |
123 | + if s.reflectType.Field(i).Tag.Get("pri") == "1" { | |
124 | + pri = strings.ToLower(s.reflectType.Field(i).Name) | |
125 | + break | |
126 | + } | |
127 | + } | |
128 | + return pri | |
129 | +} | ... | ... |
models/team.go
... | ... | @@ -2,11 +2,10 @@ package models |
2 | 2 | |
3 | 3 | import ( |
4 | 4 | "pro2d/pb" |
5 | - "pro2d/utils/db" | |
6 | 5 | ) |
7 | 6 | |
8 | 7 | type TeamModel struct { |
9 | - *db.Schema | |
8 | + *Schema | |
10 | 9 | Team *pb.Team |
11 | 10 | } |
12 | 11 | |
... | ... | @@ -15,7 +14,7 @@ func NewTeam(id string) *TeamModel { |
15 | 14 | Id: id, |
16 | 15 | } |
17 | 16 | m := &TeamModel{ |
18 | - Schema: db.NewSchema(id, data), | |
17 | + Schema: NewSchema(id, data), | |
19 | 18 | Team: data, |
20 | 19 | } |
21 | 20 | ... | ... |
utils/db/mongo.go deleted
... | ... | @@ -1,224 +0,0 @@ |
1 | -package db | |
2 | - | |
3 | -import ( | |
4 | - "context" | |
5 | - "fmt" | |
6 | - "go.mongodb.org/mongo-driver/bson" | |
7 | - "go.mongodb.org/mongo-driver/mongo" | |
8 | - "go.mongodb.org/mongo-driver/mongo/options" | |
9 | - "go.mongodb.org/mongo-driver/mongo/readpref" | |
10 | - "go.mongodb.org/mongo-driver/x/bsonx" | |
11 | - "pro2d/utils" | |
12 | - "sort" | |
13 | - "strconv" | |
14 | - "strings" | |
15 | - "time" | |
16 | -) | |
17 | - | |
18 | -var ( | |
19 | - MongoClient *mongo.Client | |
20 | - MongoDatabase *mongo.Database | |
21 | -) | |
22 | - | |
23 | -//初始化 | |
24 | -func Connect(user, password, host string,port int, MaxNum int, timeOut int) error { | |
25 | - var uri string | |
26 | - if user!= "" { | |
27 | - //uri = fmt.Sprintf("mongodb://%s:%s@%s:%d/%s?w=majority", conf.User, conf.Password, conf.Host, conf.Port, conf.DBName) | |
28 | - uri = fmt.Sprintf("mongodb://%s:%s@%s:%d/?w=majority", user, password, host, port) | |
29 | - }else { | |
30 | - //uri = fmt.Sprintf("mongodb://%s:%d/%s?w=majority", conf.Host, conf.Port, conf.DBName) | |
31 | - uri = fmt.Sprintf("mongodb://%s:%d/?w=majority", host, port) | |
32 | - } | |
33 | - // 设置连接超时时间 | |
34 | - ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeOut)) | |
35 | - defer cancel() | |
36 | - // 通过传进来的uri连接相关的配置 | |
37 | - o := options.Client().ApplyURI(uri) | |
38 | - // 设置最大连接数 - 默认是100 ,不设置就是最大 max 64 | |
39 | - o.SetMaxPoolSize(uint64(MaxNum)) | |
40 | - // 发起链接 | |
41 | - var err error | |
42 | - MongoClient, err = mongo.Connect(ctx, o) | |
43 | - if err != nil { | |
44 | - return err | |
45 | - } | |
46 | - // 判断服务是不是可用 | |
47 | - if err = MongoClient.Ping(context.Background(), readpref.Primary()); err != nil { | |
48 | - return err | |
49 | - } | |
50 | - | |
51 | - //MongoDatabase = MongoClient.Database(dbname) | |
52 | - return nil | |
53 | -} | |
54 | - | |
55 | -func CreateCollection(collection string) error { | |
56 | - colls, _ := MongoDatabase.ListCollectionNames(context.TODO(), bson.D{}) | |
57 | - pos := sort.SearchStrings(colls, collection) | |
58 | - if pos != len(colls) { | |
59 | - if collection == colls[pos] { | |
60 | - return MongoDatabase.CreateCollection(context.TODO(), collection) | |
61 | - } | |
62 | - } | |
63 | - return MongoDatabase.CreateCollection(context.TODO(), collection) | |
64 | -} | |
65 | - | |
66 | -func SetUnique(collection string, key string) (string, error) { | |
67 | - return MongoDatabase.Collection(collection).Indexes().CreateOne( | |
68 | - context.TODO(), | |
69 | - mongo.IndexModel{ | |
70 | - Keys : bsonx.Doc{{key, bsonx.Int32(1)}}, | |
71 | - Options: options.Index().SetUnique(true), | |
72 | - }, | |
73 | - ) | |
74 | -} | |
75 | - | |
76 | -type MgoColl struct { | |
77 | - collection *mongo.Collection | |
78 | - | |
79 | - schema *Schema | |
80 | -} | |
81 | - | |
82 | -func GetBsonD(key string, value interface{}) interface{} { | |
83 | - return bson.D{ {key, value}} | |
84 | -} | |
85 | -func GetBsonM(key string, value interface{}) interface{} { | |
86 | - return bson.M{key: value} | |
87 | -} | |
88 | - | |
89 | -func NewMongoColl(schema *Schema) *MgoColl { | |
90 | - return &MgoColl{ | |
91 | - collection: MongoDatabase.Collection(schema.GetCollName()), | |
92 | - schema: schema, | |
93 | - } | |
94 | -} | |
95 | - | |
96 | -func FindOne(pri interface{}, schema interface{}) error { | |
97 | - r := MongoDatabase.Collection(utils.GetCollName(schema)).FindOne(context.TODO(), pri) | |
98 | - return r.Decode(schema) | |
99 | -} | |
100 | - | |
101 | -// 查询单个 | |
102 | -func (m *MgoColl) FindOneKV(key string, value interface{}) *mongo.SingleResult { | |
103 | - //collection. | |
104 | - filter := bson.D{ {key, value}} | |
105 | - singleResult := m.collection.FindOne(context.TODO(), filter) | |
106 | - return singleResult | |
107 | -} | |
108 | - | |
109 | -//查询集合里有多少数据 | |
110 | -func (m *MgoColl) CollectionCount() (string, int64) { | |
111 | - size, _ := m.collection.EstimatedDocumentCount(context.TODO()) | |
112 | - return m.collection.Name(), size | |
113 | -} | |
114 | - | |
115 | -//按选项查询集合 Skip 跳过 Limit 读取数量 sort 1 ,-1 . 1 为最初时间读取 , -1 为最新时间读取 | |
116 | -func (m *MgoColl) CollectionDocuments(Skip, Limit int64, sort int) *mongo.Cursor { | |
117 | - SORT := bson.D{ | |
118 | - {"_id", sort}} //filter := bson.D{ {key,value}} | |
119 | - filter := bson.D{ | |
120 | - {}} | |
121 | - findOptions := options.Find().SetSort(SORT).SetLimit(Limit).SetSkip(Skip) | |
122 | - //findOptions.SetLimit(i) | |
123 | - temp, _ := m.collection.Find(context.Background(), filter, findOptions) | |
124 | - return temp | |
125 | -} | |
126 | - | |
127 | -//获取集合创建时间和编号 | |
128 | -func (m *MgoColl) ParsingId(result string) (time.Time, uint64) { | |
129 | - temp1 := result[:8] | |
130 | - timestamp, _ := strconv.ParseInt(temp1, 16, 64) | |
131 | - dateTime := time.Unix(timestamp, 0) //这是截获情报时间 时间格式 2019-04-24 09:23:39 +0800 CST | |
132 | - temp2 := result[18:] | |
133 | - count, _ := strconv.ParseUint(temp2, 16, 64) //截获情报的编号 | |
134 | - return dateTime, count | |
135 | -} | |
136 | - | |
137 | -//删除文章和查询文章 | |
138 | -func (m *MgoColl) DeleteAndFind(key string, value interface{}) (int64, *mongo.SingleResult) { | |
139 | - filter := bson.D{ | |
140 | - {key, value}} | |
141 | - singleResult := m.collection.FindOne(context.TODO(), filter) | |
142 | - DeleteResult, err := m.collection.DeleteOne(context.TODO(), filter, nil) | |
143 | - if err != nil { | |
144 | - fmt.Println("删除时出现错误,你删不掉的~") | |
145 | - } | |
146 | - return DeleteResult.DeletedCount, singleResult | |
147 | -} | |
148 | - | |
149 | -//删除文章 | |
150 | -func (m *MgoColl) Delete(key string, value interface{}) int64 { | |
151 | - filter := bson.D{ {key, value}} | |
152 | - count, err := m.collection.DeleteOne(context.TODO(), filter, nil) | |
153 | - if err != nil { | |
154 | - fmt.Println(err) | |
155 | - } | |
156 | - return count.DeletedCount | |
157 | - | |
158 | -} | |
159 | - | |
160 | -//删除多个 | |
161 | -func (m *MgoColl) DeleteMany(key string, value interface{}) int64 { | |
162 | - filter := bson.D{ {key, value}} | |
163 | - | |
164 | - count, err := m.collection.DeleteMany(context.TODO(), filter) | |
165 | - if err != nil { | |
166 | - fmt.Println(err) | |
167 | - } | |
168 | - return count.DeletedCount | |
169 | -} | |
170 | - | |
171 | -//索引 | |
172 | -func (m *MgoColl) SetUnique(key string){ | |
173 | - m.collection.Indexes().CreateOne( | |
174 | - context.Background(), | |
175 | - mongo.IndexModel{ | |
176 | - Keys : bsonx.Doc{{key, bsonx.Int32(1)}}, | |
177 | - Options: options.Index().SetUnique(true), | |
178 | - }, | |
179 | - ) | |
180 | -} | |
181 | - | |
182 | -//更新&保存 | |
183 | -func (m *MgoColl) FindOneAndUpdate(filter interface{}, update interface{})*mongo.SingleResult { | |
184 | - //filter := bson.M{"name": "x", "array.name": "b"} | |
185 | - //update := bson.M{"array.$[item].detail": "test"} | |
186 | - | |
187 | - res := m.collection.FindOneAndUpdate(context.Background(), | |
188 | - filter, | |
189 | - bson.M{"$set": update}) | |
190 | - if res.Err() != nil { | |
191 | - return nil | |
192 | - } | |
193 | - return res | |
194 | -} | |
195 | - | |
196 | -func (m *MgoColl) UpdateOne(filter interface{}, update interface{})*mongo.UpdateResult { | |
197 | - res, err := m.collection.UpdateOne(context.TODO(), filter, bson.D{{"$set", update}}) | |
198 | - if err != nil { | |
199 | - return nil | |
200 | - } | |
201 | - | |
202 | - return res | |
203 | -} | |
204 | - | |
205 | -func (m *MgoColl) Load() error{ | |
206 | - r := m.collection.FindOne(context.TODO(), m.schema.GetPri()) | |
207 | - err := r.Decode(m.schema.GetSchema()) | |
208 | - if err != nil { | |
209 | - return err | |
210 | - } | |
211 | - return nil | |
212 | -} | |
213 | - | |
214 | -func (m *MgoColl) Create() (*mongo.InsertOneResult, error){ | |
215 | - return m.collection.InsertOne(context.TODO(), m.schema.GetSchema()) | |
216 | -} | |
217 | - | |
218 | -func (m *MgoColl) UpdateProperty(key string, val interface{}) { | |
219 | - m.UpdateOne(m.schema.GetPri(), bson.M{strings.ToLower(key): val}) | |
220 | -} | |
221 | - | |
222 | -func (m *MgoColl) UpdateProperties(properties map[string]interface{}) { | |
223 | - m.UpdateOne(m.schema.GetPri(), properties) | |
224 | -} |
utils/utils.go
... | ... | @@ -3,52 +3,9 @@ package utils |
3 | 3 | import ( |
4 | 4 | "crypto/md5" |
5 | 5 | "encoding/hex" |
6 | - "reflect" | |
7 | - "strings" | |
8 | 6 | "time" |
9 | 7 | ) |
10 | 8 | |
11 | -func GetSchemaType(schema interface{}) reflect.Type { | |
12 | - s := reflect.TypeOf(schema) | |
13 | - if s.Kind() == reflect.Ptr { | |
14 | - s = reflect.TypeOf(schema).Elem() | |
15 | - } | |
16 | - return s | |
17 | -} | |
18 | - | |
19 | -func GetCollName(schema interface{}) string { | |
20 | - return strings.ToLower(GetSchemaType(schema).Name()) | |
21 | -} | |
22 | - | |
23 | -func GetPriKey(schema interface{}) string { | |
24 | - s := GetSchemaType(schema) | |
25 | - | |
26 | - var pri string | |
27 | - for i := 0; i < s.NumField(); i++ { | |
28 | - if s.Field(i).Tag.Get("pri") == "1" { | |
29 | - pri = strings.ToLower(s.Field(i).Name) | |
30 | - break | |
31 | - } | |
32 | - } | |
33 | - return pri | |
34 | -} | |
35 | - | |
36 | -func FindIndex(schema interface{}) (string, []string){ | |
37 | - s := GetSchemaType(schema) | |
38 | - | |
39 | - var index []string | |
40 | - for i := 0; i < s.NumField(); i++ { | |
41 | - if s.Field(i).Tag.Get("index") != "" { | |
42 | - js := strings.Split(s.Field(i).Tag.Get("json"), ",") | |
43 | - if len(js) == 0 { | |
44 | - continue | |
45 | - } | |
46 | - index = append(index, js[0]) | |
47 | - } | |
48 | - } | |
49 | - return strings.ToLower(s.Name()), index | |
50 | -} | |
51 | - | |
52 | 9 | func Md5V(str string) string { |
53 | 10 | h := md5.New() |
54 | 11 | h.Write([]byte(str)) | ... | ... |