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,20 +9,15 @@ import ( | ||
9 | "pro2d/models" | 9 | "pro2d/models" |
10 | 10 | ||
11 | "pro2d/common/etcd" | 11 | "pro2d/common/etcd" |
12 | - "sync" | ||
13 | ) | 12 | ) |
14 | 13 | ||
15 | type GameServer struct { | 14 | type GameServer struct { |
16 | components.IServer | 15 | components.IServer |
17 | EtcdClient *etcd.EtcdClient | 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 | options := []components.ServerOption{ | 22 | options := []components.ServerOption{ |
28 | components.WithPlugin(components.NewPlugin(sconf.PluginPath)), | 23 | components.WithPlugin(components.NewPlugin(sconf.PluginPath)), |
@@ -57,40 +52,40 @@ func (s *GameServer) Start() error { | @@ -57,40 +52,40 @@ func (s *GameServer) Start() error { | ||
57 | return s.IServer.Start() | 52 | return s.IServer.Start() |
58 | } | 53 | } |
59 | 54 | ||
60 | -func (s *GameServer) Stop() { | 55 | +func (s *GameServer) Stop() { |
61 | s.IServer.Stop() | 56 | s.IServer.Stop() |
62 | 57 | ||
63 | db.CloseMongo() | 58 | db.CloseMongo() |
64 | s.EtcdClient.Close() | 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 | agent := NewAgent(s) | 63 | agent := NewAgent(s) |
69 | agent.OnConnection(conn) | 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 | return | 71 | return |
77 | } | 72 | } |
78 | agent.(*Agent).OnMessage(msg) | 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 | return | 79 | return |
85 | } | 80 | } |
86 | agent.(*Agent).OnTimer() | 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 | return | 87 | return |
93 | } | 88 | } |
94 | agent.(*Agent).OnClose() | 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,17 +10,16 @@ import ( | ||
10 | "time" | 10 | "time" |
11 | ) | 11 | ) |
12 | 12 | ||
13 | - | ||
14 | type Connection struct { | 13 | type Connection struct { |
15 | IConnection | 14 | IConnection |
16 | net.Conn | 15 | net.Conn |
17 | Server IServer | 16 | Server IServer |
18 | Id int | 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 | readFunc chan func() | 23 | readFunc chan func() |
25 | timerFunc chan func() | 24 | timerFunc chan func() |
26 | 25 | ||
@@ -34,18 +33,18 @@ type Connection struct { | @@ -34,18 +33,18 @@ type Connection struct { | ||
34 | 33 | ||
35 | func NewConn(id int, conn net.Conn, s IServer) *Connection { | 34 | func NewConn(id int, conn net.Conn, s IServer) *Connection { |
36 | c := &Connection{ | 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 | readFunc: make(chan func(), 10), | 44 | readFunc: make(chan func(), 10), |
46 | timerFunc: make(chan func(), 10), | 45 | timerFunc: make(chan func(), 10), |
47 | 46 | ||
48 | - Status: 0, | 47 | + Status: 0, |
49 | } | 48 | } |
50 | c.connectionCallback = c.defaultConnectionCallback | 49 | c.connectionCallback = c.defaultConnectionCallback |
51 | c.messageCallback = c.defaultMessageCallback | 50 | c.messageCallback = c.defaultMessageCallback |
@@ -74,7 +73,7 @@ func (c *Connection) SetTimerCallback(cb TimerCallback) { | @@ -74,7 +73,7 @@ func (c *Connection) SetTimerCallback(cb TimerCallback) { | ||
74 | c.timerCallback = cb | 73 | c.timerCallback = cb |
75 | } | 74 | } |
76 | 75 | ||
77 | -func (c *Connection) Start() { | 76 | +func (c *Connection) Start() { |
78 | go c.write() | 77 | go c.write() |
79 | go c.read() | 78 | go c.read() |
80 | go c.listen() | 79 | go c.listen() |
@@ -96,7 +95,7 @@ func (c *Connection) Stop() { | @@ -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 | buf, err := c.Server.GetSplitter().Pack(cmd, data, errCode, 0) | 99 | buf, err := c.Server.GetSplitter().Pack(cmd, data, errCode, 0) |
101 | if err != nil { | 100 | if err != nil { |
102 | return err | 101 | return err |
@@ -113,25 +112,25 @@ func (c *Connection) Send(errCode int32, cmd uint32, data []byte) error{ | @@ -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 | defer c.quitting() | 128 | defer c.quitting() |
130 | 129 | ||
131 | for msg := range c.WBuffer { | 130 | for msg := range c.WBuffer { |
132 | n, err := c.writer.Write(msg) | 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 | return | 134 | return |
136 | } | 135 | } |
137 | if err := c.writer.Flush(); err != nil { | 136 | if err := c.writer.Flush(); err != nil { |
@@ -164,16 +163,16 @@ func (c *Connection) read() { | @@ -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 | defer c.quitting() | 167 | defer c.quitting() |
169 | 168 | ||
170 | - for { | 169 | + for { |
171 | select { | 170 | select { |
172 | - case timerFunc := <- c.timerFunc: | 171 | + case timerFunc := <-c.timerFunc: |
173 | timerFunc() | 172 | timerFunc() |
174 | - case readFunc := <- c.readFunc: | 173 | + case readFunc := <-c.readFunc: |
175 | readFunc() | 174 | readFunc() |
176 | - case <- c.Quit: | 175 | + case <-c.Quit: |
177 | return | 176 | return |
178 | } | 177 | } |
179 | } | 178 | } |
@@ -186,7 +185,7 @@ func (c *Connection) handleTimeOut() { | @@ -186,7 +185,7 @@ func (c *Connection) handleTimeOut() { | ||
186 | TimeOut(1*time.Second, c.handleTimeOut) | 185 | TimeOut(1*time.Second, c.handleTimeOut) |
187 | } | 186 | } |
188 | 187 | ||
189 | -func (c *Connection) quitting() { | 188 | +func (c *Connection) quitting() { |
190 | closed := atomic.LoadUint32(&c.Status) | 189 | closed := atomic.LoadUint32(&c.Status) |
191 | if closed == 0 { | 190 | if closed == 0 { |
192 | return | 191 | return |
@@ -196,6 +195,7 @@ func (c *Connection) quitting() { | @@ -196,6 +195,7 @@ func (c *Connection) quitting() { | ||
196 | logger.Debug("ID: %d close", c.Id) | 195 | logger.Debug("ID: %d close", c.Id) |
197 | close(c.WBuffer) | 196 | close(c.WBuffer) |
198 | close(c.Quit) | 197 | close(c.Quit) |
198 | + close(c.readFunc) | ||
199 | c.Conn.Close() | 199 | c.Conn.Close() |
200 | c.closeCallback(c) | 200 | c.closeCallback(c) |
201 | } | 201 | } |
common/components/icompontents.go
@@ -46,15 +46,23 @@ type ( | @@ -46,15 +46,23 @@ type ( | ||
46 | SetCloseCallback(CloseCallback) | 46 | SetCloseCallback(CloseCallback) |
47 | SetTimerCallback(TimerCallback) | 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 | //server | 57 | //server |
50 | IServer interface { | 58 | IServer interface { |
51 | Start() error | 59 | Start() error |
52 | Stop() | 60 | Stop() |
53 | 61 | ||
54 | GetSplitter() ISplitter | 62 | GetSplitter() ISplitter |
55 | - GetIConnection(id int) IConnection | ||
56 | GetPlugin() IPlugin | 63 | GetPlugin() IPlugin |
57 | GetAction(uint32) interface{} | 64 | GetAction(uint32) interface{} |
65 | + GetConnManage() IConnManage | ||
58 | 66 | ||
59 | SetConnectionCallback(ConnectionCallback) | 67 | SetConnectionCallback(ConnectionCallback) |
60 | SetMessageCallback(MessageCallback) | 68 | SetMessageCallback(MessageCallback) |
@@ -75,8 +83,6 @@ type ( | @@ -75,8 +83,6 @@ type ( | ||
75 | SetActions(map[interface{}]interface{}) | 83 | SetActions(map[interface{}]interface{}) |
76 | GetAction(uint32) interface{} | 84 | GetAction(uint32) interface{} |
77 | } | 85 | } |
78 | - | ||
79 | - | ||
80 | ) | 86 | ) |
81 | 87 | ||
82 | //----------------- | 88 | //----------------- |
common/components/server.go
@@ -4,7 +4,6 @@ import ( | @@ -4,7 +4,6 @@ import ( | ||
4 | "fmt" | 4 | "fmt" |
5 | "net" | 5 | "net" |
6 | "pro2d/common/logger" | 6 | "pro2d/common/logger" |
7 | - "sync" | ||
8 | ) | 7 | ) |
9 | 8 | ||
10 | type ServerOption func(*Server) | 9 | type ServerOption func(*Server) |
@@ -45,25 +44,24 @@ func WithTimerCbk(cb TimerCallback) ServerOption { | @@ -45,25 +44,24 @@ func WithTimerCbk(cb TimerCallback) ServerOption { | ||
45 | } | 44 | } |
46 | } | 45 | } |
47 | 46 | ||
48 | - | ||
49 | type Server struct { | 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 | func NewServer(port int, options ...ServerOption) IServer { | 61 | func NewServer(port int, options ...ServerOption) IServer { |
64 | s := &Server{ | 62 | s := &Server{ |
65 | - port: port, | ||
66 | - Clients: new(sync.Map), | 63 | + port: port, |
64 | + connManage: NewConnManage(), | ||
67 | } | 65 | } |
68 | for _, option := range options { | 66 | for _, option := range options { |
69 | option(s) | 67 | option(s) |
@@ -76,14 +74,6 @@ func (s *Server) GetSplitter() ISplitter { | @@ -76,14 +74,6 @@ func (s *Server) GetSplitter() ISplitter { | ||
76 | return s.splitter | 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 | func (s *Server) GetPlugin() IPlugin { | 77 | func (s *Server) GetPlugin() IPlugin { |
88 | return s.plugins | 78 | return s.plugins |
89 | } | 79 | } |
@@ -92,6 +82,10 @@ func (s *Server) GetAction(cmd uint32) interface{} { | @@ -92,6 +82,10 @@ func (s *Server) GetAction(cmd uint32) interface{} { | ||
92 | return s.plugins.GetAction(cmd) | 82 | return s.plugins.GetAction(cmd) |
93 | } | 83 | } |
94 | 84 | ||
85 | +func (s *Server) GetConnManage() IConnManage { | ||
86 | + return s.connManage | ||
87 | +} | ||
88 | + | ||
95 | func (s *Server) SetConnectionCallback(cb ConnectionCallback) { | 89 | func (s *Server) SetConnectionCallback(cb ConnectionCallback) { |
96 | s.connectionCallback = cb | 90 | s.connectionCallback = cb |
97 | } | 91 | } |
@@ -133,19 +127,12 @@ func (s *Server) Start() error { | @@ -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 | StopTimer() | 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 | func (s *Server) newConnection(conn IConnection) { | 135 | func (s *Server) newConnection(conn IConnection) { |
147 | - s.Clients.Store(conn.GetID(), conn) | ||
148 | - | ||
149 | conn.SetConnectionCallback(s.connectionCallback) | 136 | conn.SetConnectionCallback(s.connectionCallback) |
150 | conn.SetCloseCallback(s.removeConnection) | 137 | conn.SetCloseCallback(s.removeConnection) |
151 | conn.SetMessageCallback(s.messageCallback) | 138 | conn.SetMessageCallback(s.messageCallback) |
@@ -156,5 +143,4 @@ func (s *Server) newConnection(conn IConnection) { | @@ -156,5 +143,4 @@ func (s *Server) newConnection(conn IConnection) { | ||
156 | 143 | ||
157 | func (s *Server) removeConnection(conn IConnection) { | 144 | func (s *Server) removeConnection(conn IConnection) { |
158 | s.closeCallback(conn) | 145 | s.closeCallback(conn) |
159 | - s.Clients.Delete(conn.GetID()) | ||
160 | } | 146 | } |