From 53073287b26cb3a0886475944bea5751a6f2d54d Mon Sep 17 00:00:00 2001 From: aceld Date: Thu, 14 Feb 2019 14:22:58 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=93=BE=E6=8E=A5=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ziface/iconnmanager.go | 12 ++++++ znet/connection.go | 26 ++++--------- znet/connmanager.go | 85 ++++++++++++++++++++++++++++++++++++++++++ znet/server.go | 9 ++--- 4 files changed, 108 insertions(+), 24 deletions(-) create mode 100644 ziface/iconnmanager.go create mode 100644 znet/connmanager.go diff --git a/ziface/iconnmanager.go b/ziface/iconnmanager.go new file mode 100644 index 0000000..a06d9f4 --- /dev/null +++ b/ziface/iconnmanager.go @@ -0,0 +1,12 @@ +package ziface + +/* + 连接管理抽象层 + */ +type IConnManager interface { + Add(conn IConnection) //添加链接 + Remove(conn IConnection) //删除连接 + Get(connID uint32) (IConnection, error) //利用ConnID获取链接 + Len() int //获取当前连接 + ClearConn() //删除并停止所有链接 +} diff --git a/znet/connection.go b/znet/connection.go index db3aa74..50efb10 100644 --- a/znet/connection.go +++ b/znet/connection.go @@ -71,10 +71,10 @@ func NewConntion(server ziface.IServer, conn *net.TCPConn, connID uint32, msgHan return } } else { + break fmt.Println("msgBuffChan is Closed") } - case <- c.ExitBuffChan: - //conn已经关闭 + case <-c.ExitBuffChan: return } } @@ -87,8 +87,9 @@ func NewConntion(server ziface.IServer, conn *net.TCPConn, connID uint32, msgHan func (c *Connection) StartReader() { fmt.Println("[Reader Goroutine is running]") defer fmt.Println(c.RemoteAddr().String(), "[conn Reader exit!]") + defer c.Stop() - for { + for { // 创建拆包解包的对象 dp := NewDataPack() @@ -131,37 +132,22 @@ func (c *Connection) StartReader() { go c.MsgHandler.DoMsgHandler(&req) } } - - c.ExitBuffChan <- true } //启动连接,让当前连接开始工作 func (c *Connection) Start() { - //Start()函数结束的时候就应该调用Stop处理善后业务 - defer c.Stop() - //1 开启用户从客户端读取数据流程的Goroutine go c.StartReader() //2 开启用于写回客户端数据流程的Goroutine go c.StartWriter() - //按照用户传递进来的创建连接时需要处理的业务,执行钩子方法 c.TcpServer.CallOnConnStart(c) - - for { - select { - case <- c.ExitBuffChan: - //得到退出消息,不再阻塞 - fmt.Println("Start recv ExitBuffChan...") - return - } - } } //停止连接,结束当前连接状态M func (c *Connection) Stop() { fmt.Println("Conn Stop()...ConnID = ", c.ConnID) - //1. 如果当前链接已经关闭 + //如果当前链接已经关闭 if c.isClosed == true { return } @@ -172,6 +158,8 @@ func (c *Connection) Stop() { // 关闭socket链接 c.Conn.Close() + //关闭Writer + c.ExitBuffChan <- true //将链接从连接管理器中删除 c.TcpServer.GetConnMgr().Remove(c) diff --git a/znet/connmanager.go b/znet/connmanager.go new file mode 100644 index 0000000..03e4f1c --- /dev/null +++ b/znet/connmanager.go @@ -0,0 +1,85 @@ +package znet + +import ( + "errors" + "fmt" + "sync" + "zinx/ziface" +) + +/* + 连接管理模块 +*/ +type ConnManager struct { + connections map[uint32]ziface.IConnection //管理的连接信息 + connLock sync.RWMutex //读写连接的读写锁 +} + +/* + 创建一个链接管理 + */ +func NewConnManager() *ConnManager { + return &ConnManager{ + connections:make(map[uint32] ziface.IConnection), + } +} + +//添加链接 +func (connMgr *ConnManager) Add(conn ziface.IConnection) { + //保护共享资源Map 加写锁 + connMgr.connLock.Lock() + defer connMgr.connLock.Unlock() + + //将conn连接添加到ConnMananger中 + connMgr.connections[conn.GetConnID()] = conn + + fmt.Println("connection add to ConnManager successfully: conn num = ", connMgr.Len()) +} + +//删除连接 +func (connMgr *ConnManager) Remove(conn ziface.IConnection) { + //保护共享资源Map 加写锁 + connMgr.connLock.Lock() + defer connMgr.connLock.Unlock() + + //删除连接信息 + delete(connMgr.connections, conn.GetConnID()) + + fmt.Println("connection Remove ConnID=",conn.GetConnID(), " successfully: conn num = ", connMgr.Len()) +} + +//利用ConnID获取链接 +func (connMgr *ConnManager) Get(connID uint32) (ziface.IConnection, error) { + //保护共享资源Map 加读锁 + connMgr.connLock.RLock() + defer connMgr.connLock.RUnlock() + + if conn, ok := connMgr.connections[connID]; ok { + return conn, nil + } else { + return nil, errors.New("connection not found") + } +} + +//获取当前连接 +func (connMgr *ConnManager) Len() int { + return len(connMgr.connections) +} + +//清除并停止所有连接 +func (connMgr *ConnManager) ClearConn() { + //保护共享资源Map 加写锁 + connMgr.connLock.Lock() + defer connMgr.connLock.Unlock() + + //停止并删除全部的连接信息 + for connID, conn := range connMgr.connections { + //停止 + conn.Stop() + //删除 + delete(connMgr.connections,connID) + } + + + fmt.Println("Clear All Connections successfully: conn num = ", connMgr.Len()) +} diff --git a/znet/server.go b/znet/server.go index 7f12156..9fc67bd 100644 --- a/znet/server.go +++ b/znet/server.go @@ -107,7 +107,8 @@ func (s *Server) Start() { func (s *Server) Stop() { fmt.Println("[STOP] Zinx server , name " , s.Name) - //TODO Server.Stop() 将其他需要清理的连接信息或者其他信息 也要一并停止或者清理 + //将其他需要清理的连接信息或者其他信息 也要一并停止或者清理 + s.ConnMgr.ClearConn() } func (s *Server) Serve() { @@ -142,6 +143,7 @@ func (s *Server) SetOnConnStop(hookFunc func (ziface.IConnection)) { //调用连接OnConnStart Hook函数 func (s *Server) CallOnConnStart(conn ziface.IConnection) { if s.OnConnStart != nil { + fmt.Println("---> CallOnConnStart....") s.OnConnStart(conn) } } @@ -149,13 +151,10 @@ func (s *Server) CallOnConnStart(conn ziface.IConnection) { //调用连接OnConnStop Hook函数 func (s *Server) CallOnConnStop(conn ziface.IConnection) { if s.OnConnStop != nil { + fmt.Println("---> CallOnConnStop....") s.OnConnStop(conn) } } -//捕捉信号处理函数,对服务器退出平滑处理 -func (s *Server) WaitSignal() { - -}