Commit cd2f96ab70602424ec48f1ad23292ba7aa45c231

Authored by zhangqijia
1 parent 364620cd

fix: 优化连接管理

只使用一份连接管理,把数据放在底层,操作放在应用层
cmd/gameserver/game.go
... ... @@ -9,20 +9,15 @@ import (
9 9 "pro2d/models"
10 10  
11 11 "pro2d/common/etcd"
12   - "sync"
13 12 )
14 13  
15 14 type GameServer struct {
16 15 components.IServer
17 16 EtcdClient *etcd.EtcdClient
18   -
19   - Agents *sync.Map
20 17 }
21 18  
22   -func NewGameServer(sconf *common.SConf) (*GameServer, error) {
23   - s := &GameServer{
24   - Agents: new(sync.Map),
25   - }
  19 +func NewGameServer(sconf *common.SConf) (*GameServer, error) {
  20 + s := &GameServer{}
26 21  
27 22 options := []components.ServerOption{
28 23 components.WithPlugin(components.NewPlugin(sconf.PluginPath)),
... ... @@ -57,40 +52,40 @@ func (s *GameServer) Start() error {
57 52 return s.IServer.Start()
58 53 }
59 54  
60   -func (s *GameServer) Stop() {
  55 +func (s *GameServer) Stop() {
61 56 s.IServer.Stop()
62 57  
63 58 db.CloseMongo()
64 59 s.EtcdClient.Close()
65 60 }
66 61  
67   -func (s *GameServer) OnConnection(conn components.IConnection) {
  62 +func (s *GameServer) OnConnection(conn components.IConnection) {
68 63 agent := NewAgent(s)
69 64 agent.OnConnection(conn)
70   - s.Agents.Store(conn.GetID(),agent)
  65 + s.GetConnManage().AddConn(conn.GetID(), agent)
71 66 }
72 67  
73   -func (s *GameServer) OnMessage(msg components.IMessage) {
74   - agent, ok := s.Agents.Load(msg.GetSession().GetID())
75   - if !ok {
  68 +func (s *GameServer) OnMessage(msg components.IMessage) {
  69 + agent := s.GetConnManage().GetConn(msg.GetSession().GetID())
  70 + if agent == nil {
76 71 return
77 72 }
78 73 agent.(*Agent).OnMessage(msg)
79 74 }
80 75  
81   -func (s *GameServer) OnTimer(conn components.IConnection) {
82   - agent, ok := s.Agents.Load(conn.GetID())
83   - if !ok {
  76 +func (s *GameServer) OnTimer(conn components.IConnection) {
  77 + agent := s.GetConnManage().GetConn(conn.GetID())
  78 + if agent == nil {
84 79 return
85 80 }
86 81 agent.(*Agent).OnTimer()
87 82 }
88 83  
89   -func (s *GameServer) OnClose(conn components.IConnection) {
90   - agent, ok := s.Agents.Load(conn.GetID())
91   - if !ok {
  84 +func (s *GameServer) OnClose(conn components.IConnection) {
  85 + agent := s.GetConnManage().GetConn(conn.GetID())
  86 + if agent == nil {
92 87 return
93 88 }
94 89 agent.(*Agent).OnClose()
95   - s.Agents.Delete(conn.GetID())
  90 + s.GetConnManage().DelConn(conn.GetID())
96 91 }
... ...
common/components/conn.go
... ... @@ -10,17 +10,16 @@ import (
10 10 "time"
11 11 )
12 12  
13   -
14 13 type Connection struct {
15 14 IConnection
16 15 net.Conn
17 16 Server IServer
18 17 Id int
19 18  
20   - scanner *bufio.Scanner
21   - writer *bufio.Writer
22   - WBuffer chan []byte
23   - Quit chan *Connection
  19 + scanner *bufio.Scanner
  20 + writer *bufio.Writer
  21 + WBuffer chan []byte
  22 + Quit chan *Connection
24 23 readFunc chan func()
25 24 timerFunc chan func()
26 25  
... ... @@ -34,18 +33,18 @@ type Connection struct {
34 33  
35 34 func NewConn(id int, conn net.Conn, s IServer) *Connection {
36 35 c := &Connection{
37   - Id: id,
38   - Conn: conn,
39   - Server: s,
40   -
41   - scanner: bufio.NewScanner(conn),
42   - writer: bufio.NewWriter(conn),
43   - WBuffer: make(chan []byte, common.MaxMsgChan),
44   - Quit: make(chan *Connection),
  36 + Id: id,
  37 + Conn: conn,
  38 + Server: s,
  39 +
  40 + scanner: bufio.NewScanner(conn),
  41 + writer: bufio.NewWriter(conn),
  42 + WBuffer: make(chan []byte, common.MaxMsgChan),
  43 + Quit: make(chan *Connection),
45 44 readFunc: make(chan func(), 10),
46 45 timerFunc: make(chan func(), 10),
47 46  
48   - Status: 0,
  47 + Status: 0,
49 48 }
50 49 c.connectionCallback = c.defaultConnectionCallback
51 50 c.messageCallback = c.defaultMessageCallback
... ... @@ -74,7 +73,7 @@ func (c *Connection) SetTimerCallback(cb TimerCallback) {
74 73 c.timerCallback = cb
75 74 }
76 75  
77   -func (c *Connection) Start() {
  76 +func (c *Connection) Start() {
78 77 go c.write()
79 78 go c.read()
80 79 go c.listen()
... ... @@ -96,7 +95,7 @@ func (c *Connection) Stop() {
96 95 }
97 96 }
98 97  
99   -func (c *Connection) Send(errCode int32, cmd uint32, data []byte) error{
  98 +func (c *Connection) Send(errCode int32, cmd uint32, data []byte) error {
100 99 buf, err := c.Server.GetSplitter().Pack(cmd, data, errCode, 0)
101 100 if err != nil {
102 101 return err
... ... @@ -113,25 +112,25 @@ func (c *Connection) Send(errCode int32, cmd uint32, data []byte) error{
113 112 }
114 113 }
115 114  
116   -func (c *Connection) defaultConnectionCallback(conn IConnection) {
  115 +func (c *Connection) defaultConnectionCallback(conn IConnection) {
117 116 }
118 117  
119   -func (c *Connection) defaultMessageCallback(msg IMessage) {
  118 +func (c *Connection) defaultMessageCallback(msg IMessage) {
120 119 }
121 120  
122   -func (c *Connection) defaultCloseCallback(conn IConnection) {
  121 +func (c *Connection) defaultCloseCallback(conn IConnection) {
123 122 }
124 123  
125   -func (c *Connection) defaultTimerCallback(conn IConnection) {
  124 +func (c *Connection) defaultTimerCallback(conn IConnection) {
126 125 }
127 126  
128   -func (c *Connection) write() {
  127 +func (c *Connection) write() {
129 128 defer c.quitting()
130 129  
131 130 for msg := range c.WBuffer {
132 131 n, err := c.writer.Write(msg)
133   - if err != nil{
134   - logger.Error("write fail err: " + err.Error(), "n: ", n)
  132 + if err != nil {
  133 + logger.Error("write fail err: "+err.Error(), "n: ", n)
135 134 return
136 135 }
137 136 if err := c.writer.Flush(); err != nil {
... ... @@ -164,16 +163,16 @@ func (c *Connection) read() {
164 163 }
165 164  
166 165 //此设计目的是为了让网络数据与定时器处理都在一条协程里处理。不想加锁。。。
167   -func (c *Connection) listen(){
  166 +func (c *Connection) listen() {
168 167 defer c.quitting()
169 168  
170   - for {
  169 + for {
171 170 select {
172   - case timerFunc := <- c.timerFunc:
  171 + case timerFunc := <-c.timerFunc:
173 172 timerFunc()
174   - case readFunc := <- c.readFunc:
  173 + case readFunc := <-c.readFunc:
175 174 readFunc()
176   - case <- c.Quit:
  175 + case <-c.Quit:
177 176 return
178 177 }
179 178 }
... ... @@ -186,7 +185,7 @@ func (c *Connection) handleTimeOut() {
186 185 TimeOut(1*time.Second, c.handleTimeOut)
187 186 }
188 187  
189   -func (c *Connection) quitting() {
  188 +func (c *Connection) quitting() {
190 189 closed := atomic.LoadUint32(&c.Status)
191 190 if closed == 0 {
192 191 return
... ... @@ -196,6 +195,7 @@ func (c *Connection) quitting() {
196 195 logger.Debug("ID: %d close", c.Id)
197 196 close(c.WBuffer)
198 197 close(c.Quit)
  198 + close(c.readFunc)
199 199 c.Conn.Close()
200 200 c.closeCallback(c)
201 201 }
... ...
common/components/icompontents.go
... ... @@ -46,15 +46,23 @@ type (
46 46 SetCloseCallback(CloseCallback)
47 47 SetTimerCallback(TimerCallback)
48 48 }
  49 + //connManage
  50 + IConnManage interface {
  51 + AddConn(id int, connection IConnection)
  52 + GetConn(id int) IConnection
  53 + DelConn(id int) IConnection
  54 + Range(f func(key interface{}, value interface{}) bool)
  55 + StopAllConns()
  56 + }
49 57 //server
50 58 IServer interface {
51 59 Start() error
52 60 Stop()
53 61  
54 62 GetSplitter() ISplitter
55   - GetIConnection(id int) IConnection
56 63 GetPlugin() IPlugin
57 64 GetAction(uint32) interface{}
  65 + GetConnManage() IConnManage
58 66  
59 67 SetConnectionCallback(ConnectionCallback)
60 68 SetMessageCallback(MessageCallback)
... ... @@ -75,8 +83,6 @@ type (
75 83 SetActions(map[interface{}]interface{})
76 84 GetAction(uint32) interface{}
77 85 }
78   -
79   -
80 86 )
81 87  
82 88 //-----------------
... ...
common/components/server.go
... ... @@ -4,7 +4,6 @@ import (
4 4 "fmt"
5 5 "net"
6 6 "pro2d/common/logger"
7   - "sync"
8 7 )
9 8  
10 9 type ServerOption func(*Server)
... ... @@ -45,25 +44,24 @@ func WithTimerCbk(cb TimerCallback) ServerOption {
45 44 }
46 45 }
47 46  
48   -
49 47 type Server struct {
50   - PluginPath string
51   - plugins IPlugin
52   - splitter ISplitter
  48 + PluginPath string
  49 + plugins IPlugin
  50 + splitter ISplitter
53 51  
54   - connectionCallback ConnectionCallback
55   - messageCallback MessageCallback
56   - closeCallback CloseCallback
57   - timerCallback TimerCallback
  52 + connectionCallback ConnectionCallback
  53 + messageCallback MessageCallback
  54 + closeCallback CloseCallback
  55 + timerCallback TimerCallback
58 56  
59   - port int
60   - Clients *sync.Map
  57 + port int
  58 + connManage *ConnManage
61 59 }
62 60  
63 61 func NewServer(port int, options ...ServerOption) IServer {
64 62 s := &Server{
65   - port: port,
66   - Clients: new(sync.Map),
  63 + port: port,
  64 + connManage: NewConnManage(),
67 65 }
68 66 for _, option := range options {
69 67 option(s)
... ... @@ -76,14 +74,6 @@ func (s *Server) GetSplitter() ISplitter {
76 74 return s.splitter
77 75 }
78 76  
79   -func (s *Server) GetIConnection(id int) IConnection {
80   - c, ok := s.Clients.Load(id)
81   - if !ok {
82   - return nil
83   - }
84   - return c.(IConnection)
85   -}
86   -
87 77 func (s *Server) GetPlugin() IPlugin {
88 78 return s.plugins
89 79 }
... ... @@ -92,6 +82,10 @@ func (s *Server) GetAction(cmd uint32) interface{} {
92 82 return s.plugins.GetAction(cmd)
93 83 }
94 84  
  85 +func (s *Server) GetConnManage() IConnManage {
  86 + return s.connManage
  87 +}
  88 +
95 89 func (s *Server) SetConnectionCallback(cb ConnectionCallback) {
96 90 s.connectionCallback = cb
97 91 }
... ... @@ -133,19 +127,12 @@ func (s *Server) Start() error {
133 127 }
134 128 }
135 129  
136   -func (s *Server)Stop() {
  130 +func (s *Server) Stop() {
137 131 StopTimer()
138 132  
139   - s.Clients.Range(func(key, value interface{}) bool {
140   - client := value.(IConnection)
141   - client.Stop()
142   - return true
143   - })
144 133 }
145 134  
146 135 func (s *Server) newConnection(conn IConnection) {
147   - s.Clients.Store(conn.GetID(), conn)
148   -
149 136 conn.SetConnectionCallback(s.connectionCallback)
150 137 conn.SetCloseCallback(s.removeConnection)
151 138 conn.SetMessageCallback(s.messageCallback)
... ... @@ -156,5 +143,4 @@ func (s *Server) newConnection(conn IConnection) {
156 143  
157 144 func (s *Server) removeConnection(conn IConnection) {
158 145 s.closeCallback(conn)
159   - s.Clients.Delete(conn.GetID())
160 146 }
... ...