Zinx-V0.9链接管理

Zinx-V0.9链接管理

我们要为Zinx框架增加链接个数的限定,如果超过一定量的客户端个数,Zinx为了保证后端的及时响应,而拒绝链接请求。

1.在抽象层添加链接管理模块的一些方法
type IConnManager interface {
	//添加链接
	Add(conn IConnection)
	//删除链接
	Remove(connID uint32)
	//根据链接ID得到链接
	Get(connID uint32) (IConnection, error)
	//得到目前服务器的链接总个数
	Len() int
	//清空全部链接的方法
	ClearConn()
}
2.在实现层实现这些方法
type ConnManager struct {
	connections map[uint32] ziface.IConnection //管理的全部的链接
	connLock  sync.RWMutex
}

func NewConnManager() ziface.IConnManager {
	return &ConnManager{
		connections:make(map[uint32] ziface.IConnection),
	}
}


//添加链接
func (connMgr *ConnManager) Add(conn ziface.IConnection) {
	//加锁
	connMgr.connLock.Lock()
	defer connMgr.connLock.Unlock()

	connMgr.connections[conn.GetConnID()] = conn

	fmt.Println("Add connid = ", conn.GetConnID(), "to manager succ!!")
}

//删除链接
func (connMgr *ConnManager) Remove(connID uint32) {
	//加锁
	connMgr.connLock.Lock()
	defer connMgr.connLock.Unlock()

	delete(connMgr.connections,  connID)
	fmt.Println("Remove connid = ", connID, " from manager succ!!")

}
//根据链接ID得到链接
func (connMgr *ConnManager) Get(connID uint32) (ziface.IConnection, error) {
	//加读锁
	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() {
	//加锁
	connMgr.connLock.Lock()
	defer connMgr.connLock.Unlock()

	//遍历删除
	for connID, conn := range connMgr.connections {
		//将全部的conn 关闭
		conn.Stop()

		//删除链接
		delete(connMgr.connections, connID)
	}

	fmt.Println("Clear All Conections succ! conn num = ", connMgr.Len())
}
3.把链接管理模块集成到zinx
3.1.在Server中添加IConnManager属性
type Server struct {
	......
	//链接管理模块
	connMgr ziface.IConnManager
}
3.2.在Server初始化时把ConnManager也初始化
func NewServer(name string) ziface.IServer{
	s := &Server{
		Name:config.GlobalObject.Name,
		IPVersion:"tcp4",
		IP:config.GlobalObject.Host,
		Port:config.GlobalObject.Port,
		MsgHandler:NewMsgHandler(),
		connMgr:NewConnManager(),
	}

	return s
}
3.3.把每个IConnection添加到ConnManger中
3.3.1.在Connection中添加IServer属性(表示该Connection属于哪个Server)
type Connection struct {
	//当前链接是属于哪个server创建
	server ziface.IServer
	......
}
3.3.2.在Iserver中添加GetConnMgr方法
type IServer interface {
	//启动服务器
	Start()
	//停止服务器
	Stop()
	//运行服务器
	Serve()
	//提供一个得到链接管理模块的方法
	GetConnMgr() IConnManager
}

对应在Server中实现这个方法

func (s *Server) GetConnMgr() ziface.IConnManager {
	return s.connMgr
}
3.3.3.在IConnection初始化的时候将Server也初始化,并在初始化结束时将该IConnection添加到ConnManager
func NewConnection(server ziface.IServer, conn *net.TCPConn, connID uint32, handler ziface.IMsgHandler) ziface.IConnection {
	c := &Connection{
		server:server,
		Conn:conn,
		ConnID:connID,
		//handleAPI:callback_api,
		MsgHandler:handler,
		isClosed:false,
		msgChan: make(chan []byte), //初始化Reader Writer通信的Channel
		writerExitChan:make(chan bool),
	}

	//当已经成功创建一个链接的时候,添加到链接管理器中
	c.server.GetConnMgr().Add(c)

	return c
}

这时Server中初始化IConnection时应该把Iserver也添加进去

dealConn := NewConnection(s, conn, cid, s.MsgHandler)
3.4.在建立连接时进行判断,如果超过用户定义的最大连接数量,就不再建立连接
	......
//判断当前server链接数量是否已经最大值
if s.connMgr.Len() >= int(config.GlobalObject.MaxConn) {
	//当前链接已经满了
	fmt.Println("---> Too many Connection MAxConn = ", config.GlobalObject.MaxConn)
	conn.Close()
	continue
}
	......
3.5.在连接关闭的时候将对应IConnection从ConnManager中删除
func (c *Connection) Stop() {
	......
	//关闭原生套接字
	_ = c.Conn.Close()
	//将当前链接从链接管理模块删除
	c.server.GetConnMgr().Remove(c.ConnID)
	......
}
4.注册链接启动/停止自定义Hook方法功能

​ 有的时候,在创建链接的时候,希望在创建链接之后、和断开链接之前,执行一些用户自定义的业务。那么我们就需要给Zinx增添两个链接创建后和断开前时机的回调函数,一般也称作Hook(钩子)函数。

4.1.在IServer中加入对应方法
type IServer interface{
	......
	//设置该Server的连接创建时Hook函数
	AddOnConnStart(func (conn IConnection))
	//设置该Server的连接断开时的Hook函数
	AddOnConnStop(func (conn IConnection))
	//调用连接OnConnStart Hook函数
	CallOnConnStart(conn IConnection)
	//调用连接OnConnStop Hook函数
	CallOnConnStop(conn IConnection)
}
4.2.在Server中实现对应方法
type Server struct {
    ......
	//在Server的连接创建时Hook函数
	OnConnStart	func(conn ziface.IConnection)     
	//在Server的连接断开时的Hook函数
	OnConnStop func(conn ziface.IConnection)
}
//注册 创建链接之后 调用的 Hook函数 的方法
func (s *Server) AddOnConnStart(hookFunc func (ziface.IConnection)) {
	s.OnConnStart = hookFunc
}

//注册 销毁链接之前调用的Hook函数 的方法
func (s *Server) AddOnConnStop(hookFunc func (ziface.IConnection)) {
	s.OnConnStop = hookFunc
}

//调用 创建链接之后的HOOK函数的方法
func (s *Server) CallOnConnStart(conn ziface.IConnection) {
	if s.OnConnStart != nil {
		fmt.Println("---> CallOnConnStart....")
		s.OnConnStart(conn)
	}
}

//调用 销毁链接之前调用的HOOk函数的方法
func (s *Server) CallOnConnStop(conn ziface.IConnection) {
	if s.OnConnStop != nil {
		fmt.Println("---> CallOnConnStop....")
		s.OnConnStop(conn)
	}
}
4.3.在创建连接之后调用CallOnConnStart
func (c *Connection) Start() {
	fmt.Println("Conn Start()  ... id = ", c.ConnID)
	//先进行读业务
	go c.StartReader()

	//进行写业务
	go c.StartWriter()

	//调用创建链接之后  用户自定义的Hook业务
	c.server.CallOnConnStart(c)
}
4.4.在断开连接之前调用CallOnConnStop
func (c *Connection) Stop() {
	fmt.Println("c. Stop() ... ConnId = ", c.ConnID)

	//调用销毁链接之前用户自定义的Hook函数
	c.server.CallOnConnStop(c)
    
    ......
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值