Skip to content

Latest commit

 

History

History
62 lines (49 loc) · 2 KB

框架层功能-闲置连接处理.md

File metadata and controls

62 lines (49 loc) · 2 KB

闲置连接处理

客户端连接 Gateway 后, 5 分钟不发送消息,会被判断为闲置连接

闲置间隔配置

默认值 : 5 分钟

更改配置,可以以下方法之一:

  • go-xserver/common/config.go
    • 修改 ConfigRole::IdleTime 字段 Tag 中的缺省值
  • 程序启动命令行添加参数 --role-idletime ,来指定具体值
  • 设置环境变量 GOXSERVER_ROLE_IDLETIME

相关代码

user_mgr.go 文件中的 checkActive 函数

func (userMgr *UserMgr) checkActive() {
	userMgr.mutex.Lock()
	defer userMgr.mutex.Unlock()

	// 检查闲置连接
	now := userMgr.ctx.GetTickCount()
	var dels []*User
	for _, user := range userMgr.users {
		if now-user.ActiveTimestamp >= userMgr.ctx.Config().Role.IdleTime*1000 {
			dels = append(dels, user)
		}
	}

	// TODO: 删除操作现在是 1 条 1 条执行,会很慢,极端情况下,是卡玩家登录的。
	//       待优化为 REDIS PIPELINING 模式
	//       参考 : https://godoc.org/github.com/gomodule/redigo/redis#hdr-Pipelining ,类似:
	//       	c.Send("SET", "foo", "bar")
	//			c.Send("GET", "foo")
	//			c.Flush()
	//			c.Receive() // reply from SET
	//			v, err = c.Receive() // reply from GET

	// 删除闲置连接
	for _, user := range dels {
		for nodeType, serverID := range user.Servers {
			_ = serverID
			key := db.GetKeyAllocServer(nodeType, user.Account)
			ttl := userMgr.ctx.Config().Role.SessionAffinityInterval
			if _, err := userMgr.ServerRedisCli.Do("EXPIRE", key, ttl); err != nil { // 设置账号分配的服务器资源信息,过期时间 5 分钟
				userMgr.ctx.Errorln(err, "account:", user.Account)
			}
		}
		delete(userMgr.users, user.Account)
		user.ClientSession.Close()
		userMgr.ctx.Infoln("Delete user information, account:", user.Account)
	}
}

彩蛋

checkActive 函数中,留一个优化操作,优先级比较低,修改也超简单,暂时注释下,待写