Commit 765431a462c47308a5fc53e377699afdacc51c2b

Authored by zhangqijia
1 parent 77f5eec7

增加schema接口, 抽象 models + db

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   -}
... ...
cmd/gameserver/main.go 0 → 100644
... ... @@ -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
1 1 package main
2 2  
3 3 import (
  4 + "pro2d/common/logger"
4 5 "pro2d/pb"
5   - "pro2d/utils/logger"
6 6 )
7 7  
8 8 func GetActionMap() map[interface{}]interface{} {
... ...
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
... ... @@ -7,8 +7,8 @@ import (
7 7 "github.com/golang/protobuf/proto"
8 8 "net"
9 9 "pro2d/common/components"
  10 + "pro2d/common/logger"
10 11 "pro2d/pb"
11   - "pro2d/utils/logger"
12 12 "time"
13 13 )
14 14  
... ...
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
... ...
common/db/mongo.go 0 → 100644
... ... @@ -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 +}
... ...
common/db/mongoplugin.go 0 → 100644
... ... @@ -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
1   -package utils
  1 +package common
2 2  
3 3 import (
4 4 "fmt"
... ...
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))
... ...