Commit cd2f96ab70602424ec48f1ad23292ba7aa45c231
1 parent
364620cd
fix: 优化连接管理
只使用一份连接管理,把数据放在底层,操作放在应用层
Showing
4 changed files
with
69 additions
and
82 deletions
Show diff stats
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 | } | ... | ... |