添加Session容器,增加超时自动关闭Session功能 本文代码查看github:https://github.com/zboyco/go-server/tree/step-10
要实现超时管理,就需要有个地方保存所有的会话(session),我们采用 map 来存储所有的 session ,因为 session 的保存不需要顺序,同时也有删除和增加的功能,map 正好适合.
增加一个池结构,用map实现
1 2 3 4 type sessionSource struct { source map [int64 ]*AppSession mutex sync.Mutex }
再增加两个参数,分别用来设置超时时间和清理间隔
代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 type Server struct { ip string port int clientCounter int64 sessionSource *sessionSource idleSessionTimeOut int clearIdleSessionInterval int OnError func (error ) OnMessage func (*AppSession, []byte ) OnNewSessionRegister func (*AppSession) OnSessionClosed func (*AppSession, string ) }
server增加 注册session/周期性清理闲置Seesion/关闭session 三个方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 func (server *Server) registerSession(sessionID int64 , appSession *AppSession) (bool , error ) { if server.sessionSource.source[sessionID] != nil { return false , errors.New("SessionID已存在" ) } server.sessionSource.mutex.Lock() server.sessionSource.source[sessionID] = appSession server.sessionSource.mutex.Unlock() if server.OnNewSessionRegister != nil { server.OnNewSessionRegister(appSession) } return true , nil }
1 2 3 4 5 6 7 8 9 func (server *Server) closeSession(session *AppSession, reason string ) { session.Close(reason) server.sessionSource.mutex.Lock() delete (server.sessionSource.source, session.ID) server.sessionSource.mutex.Unlock() }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 func (server *Server) clearTimeoutSession(timeoutSecond int , interval int ) { var currentTime time.Time if interval == 0 { return } for { time.Sleep(time.Duration(interval) * time.Second) currentTime = time.Now() server.mutex.Lock() { for key, session := range server.sessionSource { if session.activeDateTime.Add(time.Duration(timeoutSecond) * time.Second).Before(currentTime) { fmt.Println("客户端[" , key, "]超时关闭" ) session.Close("Timeout" ) } } } server.mutex.Unlock() } }