Utm详细实现-用户生命流程
1. 用户生命流程:
首先,最基本的 就是“游客” 和“用户” 之间身份的转变:
客户端连接到服务端后,这个时候认为连接的客户端是一个游客;客户端请求登录且登录成功后则转变成一个用户;如果用户退出,则又变回游客。
然后,再看每个操作(登录、退出、断线)的具体流程:
用户登录:
用户登录过程主要分成两部分:登录检查(OnUserLoginCheckHandler) 和 登录(OnUserLoginHandler)
- 登录检查:对用户的账号密码等信息经行验证(在这个阶段,这个请求时属于一个游客发起的请求,由游客请求线程池中的线程处理)
- 登录:专注于处理登录业务(在这个阶段,这个请求已经属于一个用户发起的请求了,由utm线程调度)。(默认情况下,游客请求线程池和用户请求线程池是同一个线程池,可以根据需要更改(建议通过更改游客请求过滤器(IVisitorRequestFilter)实现类实现))
详细流程:
- 当用户发送登录请求到服务端后,先经过UTM过滤器(UserThreadModeFilter)再到 游客请求过滤器(默认实现为VisitorRequestFilterNotQueue),在游客请求过滤器中调用游客请求线程池处理该请求(触发对OnUserLoginCheckHandler的调用)。
- 在登录检查中将调用抽象方法loginCheck验证用户名密码等信息,如果失败则直接在loginCheck方法给前端返回登录失败信息,如果成功则会调用UserFlagBusiness 的设置用户标志位(SetLoginFlag)方法(用户登录标志位 是 utm最重要的标志位,用于标识用户是否已经登录,在哪里登录,详细解释可以看类UserLogoutCheckBussiness注释);如果用户没有登录,则直接将 登录任务(OnUserLoginHandler)放入用户的处理队列中,由qtm线程处理;如果用户已经登录了,则先通知在登录的用户退出登录,然后将用户的登录信息放入到UserLogoutCheckBussiness的”等待退出用户队列”中,由UserLogoutCheckBussiness继续处理(utm会保证旧的用户退出了才允许新的用户登录)。
- UserLogoutCheckBussiness是自己一个独立的线程在运行,它周期性的检查所有在队列中的用户,如果有用户已经退出了,则将 登录任务(OnUserLoginHandler)放入用户的处理队列中,由qtm线程处理;如果旧的用户超过一定时间依然没有退出,则会调用UserLogoutCheckBussiness.waitLogoutTimeOut方法,可以在其中通知前端登录失败信息。
- 接下来就到登录处理(OnUserLoginHandler),会先调用loginLinkCheck方法检查该连接是否依然在线,如果返回false则会终止登录过程并回收申请了的相关资源,如果成功则执行userLogin方法,在userLogin中处理登录的业务。
关于loginLinkCheck的详细说明:
登录成功连接检查
(该用户已经通过了登录检查,现在再次确认下连接是否还在,
如果连接已经断开了,那么将会触发回收处理
(userResource.failInLoginLinkCheck和serFlagBusiness.rollBackLoginFlagWhenLinkDisable ))
关于为什么要有loginLinkCheck问题:
有些socket的封装框架给的不是说一个socket断开了的事件或者回调(例如SmartFoxServer),而是在当用户登录后才会有用户的断线事件,设置这个loginLinkCheck方法就是为了处理这样的问题,在loginLinkCheck里面可以调用这些封装框架的登录处理,如果登录失败(用户已经断开了),那么就认为是在登录处理过程中用户断线了,也视为没有登录成功,将会回收相应的资源和标志位,如果登录成功,则接下来用户如果断线了,那么Disconect事件就会被触发=>OnUserDisconectHandler必定被触发。(也就是在loginLinkCheck中要设置用户已经登录的标志)
这个方法如果返回true, 则接下来将会执行userLogin方法,
而且用户断线OnUserDisconectHandler必定被触发,且一定在userLogin方法之后(断线事件会被放到qtm队列中,qtm保证一个用户的任务被顺序执行)
(图片看不清可以右键保存到本地后再打开浏览)
用户退出或用户断线:
用户断线和用户退出只有一个会被触发,因为用户调用退出后,其将变成游客,所以他的断线不会触发用户断线事件。用户断线和用户退出是为了处理业务上更方便区分,其都是继承AbstractOutHandler的。
详细流程:
- 当用户发送退出请求到服务端后,先经过UTM过滤器(UserThreadModeFilter)再到 用户请求过滤器(默认实现为RequestFrequentFilter),在用户请求过滤器中将 退出任务(OnUserLogoutHandler)放入用户的处理队列中,由qtm线程处理(触发对OnUserLogoutHandler的调用)。 注:如果是用户断线,则会封装成一个用户断线请求
- 在用户退出或断线处理中(AbstractOutHandler),首先会检查用户是否是登录状态(user.isLogining),如果不是登录状态则不处理(防止在用户退出后马上掉线,这个时候用户退出任务未被处理,此时认为该连接对应的是一个用户,所以会将断线事件放入任务队列中,导致用户断线和用户退出被重复调用),如果是登录状态则调用相应的业务处理方法userLogout/userDisconect
- 分发用户退出或者用户断线事件
- 通知 资源管理器 用户退出
- 调用UserFlagBusiness. removeLoginFlag 回收用户标志位(详细解释可以看类UserLogoutCheckBussiness注释)
(图片看不清可以右键保存到本地后再打开浏览)