diff --git a/demo/Client.go b/demo/Client.go index 4b7e30b..356680f 100644 --- a/demo/Client.go +++ b/demo/Client.go @@ -21,7 +21,7 @@ func main() { for { dp := wkNet.NewDataPack() - binaryMsg, err := dp.Pack(wkNet.NewMessage(0, []byte("LiuLiGamesV0.8 client0 Test Message "))) + binaryMsg, err := dp.Pack(wkNet.NewMessage(0, []byte("LiuLiGamesV0.9 client0 Test Message "))) if err != nil { fmt.Println("Pack error", err) } diff --git a/demo/Client1.go b/demo/Client1.go index 50c7880..322bcf0 100644 --- a/demo/Client1.go +++ b/demo/Client1.go @@ -21,7 +21,7 @@ func main() { for { dp := wkNet.NewDataPack() - binaryMsg, err := dp.Pack(wkNet.NewMessage(1, []byte("LiuLiGamesV0.8 client1 Test Message "))) + binaryMsg, err := dp.Pack(wkNet.NewMessage(1, []byte("LiuLiGamesV0.9 client1 Test Message "))) if err != nil { fmt.Println("Pack error", err) } diff --git a/demo/conf/conf.yaml b/demo/conf/conf.yaml index cb8bc94..8f321da 100644 --- a/demo/conf/conf.yaml +++ b/demo/conf/conf.yaml @@ -1,4 +1,4 @@ -name: "liuLI V0.8 demoServerApp" +name: "liuLI V0.9 demoServerApp" Host: "127.0.0.1" TcpPort: 9527 MaxConn: 3 diff --git a/iface/IConnManager.go b/iface/IConnManager.go new file mode 100644 index 0000000..060053e --- /dev/null +++ b/iface/IConnManager.go @@ -0,0 +1,13 @@ +package iface + +type IConnManager interface { + Add(conn IConnection) + + Remove(conn IConnection) + + Get(connId uint32) (IConnection, error) + + Len() int + + ClearConn() +} diff --git a/iface/IServer.go b/iface/IServer.go index 01768a2..965f5b1 100644 --- a/iface/IServer.go +++ b/iface/IServer.go @@ -6,4 +6,5 @@ type IServer interface { Serve() AddRouter(msgId uint32, router IRouter) + GetConnManager() IConnManager } diff --git a/net/ConnManager.go b/net/ConnManager.go new file mode 100644 index 0000000..032a2e5 --- /dev/null +++ b/net/ConnManager.go @@ -0,0 +1,66 @@ +package net + +import ( + "errors" + "fmt" + "sync" + "wukong/iface" +) + +type ConnManager struct { + connections map[uint32]iface.IConnection + connLock sync.RWMutex +} + +func NewConnManager() *ConnManager { + return &ConnManager{ + connections: make(map[uint32]iface.IConnection), + } +} + +func (cm *ConnManager) Add(conn iface.IConnection) { + cm.connLock.Lock() + defer cm.connLock.Unlock() + + cm.connections[conn.GetConnID()] = conn + fmt.Println("connId = ", conn.GetConnID(), " add to ConnManager conn num = ", cm.Len()) + +} + +func (cm *ConnManager) Remove(conn iface.IConnection) { + cm.connLock.Lock() + defer cm.connLock.Unlock() + + delete(cm.connections, conn.GetConnID()) + fmt.Println("connId = ", conn.GetConnID(), " remove to ConnManager conn num = ", cm.Len()) + +} + +func (cm *ConnManager) Get(connId uint32) (iface.IConnection, error) { + cm.connLock.RLock() + defer cm.connLock.RUnlock() + + if conn, ok := cm.connections[connId]; ok { + return conn, nil + } else { + return nil, errors.New("connection not found") + } +} + +func (cm *ConnManager) Len() int { + return len(cm.connections) +} + +func (cm *ConnManager) ClearConn() { + cm.connLock.Lock() + defer cm.connLock.Unlock() + + for connId, conn := range cm.connections { + conn.Stop() + + delete(cm.connections, connId) + } + + fmt.Println("clear all connection conn num = ", cm.Len()) + +} diff --git a/net/Connection.go b/net/Connection.go index d44640b..ad988bf 100644 --- a/net/Connection.go +++ b/net/Connection.go @@ -10,6 +10,7 @@ import ( ) type Connection struct { + TcpServer iface.IServer Conn *net.TCPConn ConnID uint32 isClosed bool @@ -18,8 +19,9 @@ type Connection struct { MsgHandler iface.IMsgHandler } -func NewConnection(conn *net.TCPConn, connID uint32, msgHandler iface.IMsgHandler) *Connection { - return &Connection{ +func NewConnection(tcpServer iface.IServer, conn *net.TCPConn, connID uint32, msgHandler iface.IMsgHandler) *Connection { + c := &Connection{ + TcpServer: tcpServer, Conn: conn, ConnID: connID, MsgHandler: msgHandler, @@ -27,6 +29,8 @@ func NewConnection(conn *net.TCPConn, connID uint32, msgHandler iface.IMsgHandle msgChan: make(chan []byte), ExitChan: make(chan bool, 1), } + c.TcpServer.GetConnManager().Add(c) + return c } func (c *Connection) StartReader() { @@ -118,6 +122,8 @@ func (c *Connection) Stop() { c.ExitChan <- true + c.TcpServer.GetConnManager().Remove(c) + close(c.ExitChan) close(c.msgChan) } diff --git a/net/Server.go b/net/Server.go index abb8ecb..28ed8de 100644 --- a/net/Server.go +++ b/net/Server.go @@ -8,11 +8,12 @@ import ( ) type Server struct { - Name string - IPVersion string - IP string - Port int - MsgHandler iface.IMsgHandler + Name string + IPVersion string + IP string + Port int + MsgHandler iface.IMsgHandler + ConnManager iface.IConnManager } func (s *Server) Start() { @@ -26,7 +27,6 @@ func (s *Server) Start() { s.MsgHandler.StartWorkerPool() - addr, err := net.ResolveTCPAddr(s.IPVersion, fmt.Sprintf("%s:%d", s.IP, s.Port)) if err != nil { fmt.Println("resolve tcp addr error :", err) @@ -50,7 +50,15 @@ func (s *Server) Start() { continue } - dealConn := NewConnection(conn, connId, s.MsgHandler) + if s.ConnManager.Len() >= utils.GlobalObject.MaxConn { + fmt.Println("too many connections maxConn = ", utils.GlobalObject.MaxConn) + if err := conn.Close(); err != nil { + fmt.Println("MaxConn Close error :", err) + } + continue + } + + dealConn := NewConnection(s, conn, connId, s.MsgHandler) connId++ go dealConn.Start() @@ -59,7 +67,8 @@ func (s *Server) Start() { } func (s *Server) Stop() { - + fmt.Println("stop server name", s.Name) + s.ConnManager.ClearConn() } func (s *Server) Serve() { @@ -75,12 +84,17 @@ func (s *Server) AddRouter(msgId uint32, router iface.IRouter) { fmt.Println("Add Router !!!!") } +func (s *Server) GetConnManager() iface.IConnManager { + return s.ConnManager +} + func NewServer() iface.IServer { return &Server{ - Name: utils.GlobalObject.Name, - IPVersion: "tcp4", - IP: utils.GlobalObject.Host, - Port: utils.GlobalObject.TcpPort, - MsgHandler: NewMsgHandler(), + Name: utils.GlobalObject.Name, + IPVersion: "tcp4", + IP: utils.GlobalObject.Host, + Port: utils.GlobalObject.TcpPort, + MsgHandler: NewMsgHandler(), + ConnManager: NewConnManager(), } } diff --git a/utils/globalobj.go b/utils/globalobj.go index 9047ebb..b2f461e 100644 --- a/utils/globalobj.go +++ b/utils/globalobj.go @@ -35,7 +35,7 @@ func (g *GlobalObj) Reload() { func init() { GlobalObject = &GlobalObj{ Name: "LiuLIServerApp", - Version: "V0.8", + Version: "V0.9", TcpPort: 9527, Host: "0.0.0.0", MaxConn: 1000,