Utm示例-公共部分
首先实现各个事件(登录检查、登录、退出、断线)的处理
1. 登录检查:
继承com.dc.utm.handler.login.OnUserLoginCheckHandler类,实现抽象方法:
queueFull:队列满:在该方法中给前端发送信息提示服务器繁忙不受理该请求
loginCheck:登录检查:检查用户的信息是否正确等,如果错误或者不允许登录则给用户返回错误提示并在该方法返回null(程序不会再往下执行),如果通过检查则返回相应的User对象。
logoutLocalUserWhenUserReLogin:退出在服务上的老用户:当通过登录检查后,OnUserLoginCheckHandler就会调用UserFlagBusiness的setLoginFlag方法(该方法会返回成功、用户在本服务登录、用户在其他服务登录)(具体说明可以看该类说明,该类有个简单实现SimpleLocalUserFlagBusiness(仅用于单个服务,并不建议使用,详见UserFlagBusiness说明)),如果返回用户在本服务登录则会调用这个方法;在该方法需要退出在本服务登录的用户。
logoutRemoteUserWhenUserReLogin:退出在其他服务上登录的用户:通知其他服务退出该用户。
2. 登录:
继承com.dc.utm.handler.login. OnUserLoginHandler类,实现抽象方法:
loginLinkCheck:登录连接检查(在“Utm详细实现 ->用户生命流程 -> 用户登录 -> 详细流程”中已有说明):在服务上登录成功返回 true,登录失败返回false(可以参考sfs的实现和netty的实现)。
userLogin:用户登录成功:用户登录成功后的业务处理和 给前端返回登录成功。
3. 退出:
继承com.dc.utm.handler.logout.OnUserDisconectHandler类,实现抽象方法:
注:LogoutHandler 和OnUserDisconectHandler只有一个会被触发 (LogoutHandler后用户将认为是游客,其断线将不会触发OnUserDisconectHandler)
userLogout:用户退出:用户退出的业务处理和 给前端返回退出成功。
4. 断线:
继承com.dc.utm.handler.logout.OnUserDisconectHandler类,实现抽象方法:
注:LogoutHandler 和OnUserDisconectHandler只有一个会被触发 (LogoutHandler后用户将认为是游客,其断线将不会触发OnUserDisconectHandler)
userDisconect:用户断线:用户断线的业务处理。
然后需要实现用户退出线程(UserLogoutCheckBusiness)的抽象方法:
(用户登录时,如果该用户之前已经登录到服务上,则utm会等待老的用户退出后,才执行新的登录,由这个线程在查看老的用户是否登出,utm在UserFlagBusiness的setLoginFlag方法返回不成功时会自动将用户放入到该实例的等待处理用户中)
waitLogoutTimeOut:等待时间超过maxWaitLogoutTime毫秒,用户依然未从原来的服务上退出 (该方法主要是负责通知前端说登录失败)
接着是实例化utm:(sfs和netty实例化只有细微差别,这里给出sfs的示例):
1.创建两个cmd对应处理器的Map,在后面我们会往其中加入处理器(在sfs中cmd只能是string类型)
//游客请求cmd和对应的请求处理器
Map<String,IRequestHandler> visitorCmdMapHandler =new HashMap<String, IRequestHandler>();
//用户请求cmd和对应的请求处理器
Map<String,IRequestHandler> userCmdMapHandler =new HashMap<String, IRequestHandler>();
2.定义utm的线程池,其中参数32,32为线程数(可以根据实际情况设置),参数500为线程池的队列长度(详细说明见:utm线程模型说明)
//线程池
LimitedUnboundedThreadPoolExecutorpool =
new LimitedUnboundedThreadPoolExecutor(32, 32,0L,
TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>(), 500);
3.定义事件管理器(提供了 "用户事件", "异常处理事件", "请求了没有注册的cmd事件", "用户请求过于频繁事件" 的基本实现,如有需要可以继承重写该类)
//事件管理器
EventManager<String,Integer, Visitor, Integer, User> eventManager =new EventManager<String, Integer, Visitor,Integer, User>();
4.实例化Utm(在构造方法中需要指定 登录的cmd 和 断线的cmd)
//实例化utm模型
userThreadMode
= new UserThreadMode<String, Integer, Visitor, Integer, User>(
Cmd.Login.CMD, Cmd.DisConect.CMD, visitorCmdMapHandler, userCmdMapHandler,pool, eventManager);
5.在资源中心中添加用户日志管理器(每个用户的请求和返回的日志,每个用户对应一个目录,如果使用需要注意:1.操作系统中一个进程最大的打开文件的个数,2.操作系统中一个目录下最大的文件数量(这里会采用分级目录的形式确保每一个目录下的文件数量可控))
(这里并非是utm的内容,但可以借鉴该日志资源管理类的申请资源和释放资源)
//添加用户日志资源管理器
userThreadMode.getUserResourceManager().getUserResourceCenter().addUserResource(new UserLoggerResource() );
6.实例化用户标志位管理(在该类中有详细的说明)
//用户登录标志位管理(仅测试,详见该类说明和UserFlagBusiness说明)
SimpleLocalUserFlagBusiness<Visitor,Integer, User> userFlagBusiness =new SimpleLocalUserFlagBusiness<Visitor,Integer, User>();
7.实例化用户登录处理类(用户登录成功后会调用的处理类)
//实例化用户登录处理类(注意:该类不需要注册到userCmdMapHandler中,如果用户登录检查通过,utm会自动调用该实例处理用户登录)
OnUserLoginHandleronUserLoginHandler = new OnUserLoginHandler(userThreadMode.getUserCenter(),eventManager,
userFlagBusiness, userThreadMode.getUserResourceManager().getUserQueueResource(),
userThreadMode.getUserResourceManager().getUserResourceCenter());
8.老用户处理退出线程(上面已经提到)(用户登录时,如果该用户已经在其他客户端登录到服务上,则utm会等待老的用户退出后,才执行新的登录,由这个线程在查看老的用户是否登出)(在后面会启动该线程)
//实例化老用户退出处理类(用户退出检查线程)
UserLogoutConfirmRunnableuserLogoutCheckBusiness =new UserLogoutConfirmRunnable(userThreadMode.getUserCenter(),
userThreadMode.getUserResourceManager().getUserQueueResource(),userThreadMode.getUserRequestFilter(), userFlagBusiness,
onUserLoginHandler, eventManager,userThreadMode.getUserResourceManager().getUserResourceCenter());
9.用户登录检查(登录检查前,连接还不是用户,所以应该放在游客cmd处理器的Map中,如果该检查成功后,就会创建用户相关的资源,并调用前面第7步的用户登录处理类)
//注册游客登录检查的处理器
visitorCmdMapHandler.put(Cmd.Login.CMD,newOnUserLoginCheckHandler(userThreadMode.getUserCenter(), eventManager,
userThreadMode.getUserResourceManager().getUserQueueResource(),userThreadMode.getUserRequestFilter(), userFlagBusiness,
userLogoutCheckBusiness, onUserLoginHandler,userThreadMode.getUserResourceManager().getUserResourceCenter() ));
10.用户断线处理器
//注册用户断线的处理器
userCmdMapHandler.put(Cmd.DisConect.CMD,newOnUserDisconectHandler(userThreadMode.getUserCenter(), eventManager,
userFlagBusiness, userThreadMode.getUserResourceManager().getUserResourceCenter() ));
11.用户退出处理器
//注册用户退出的处理器
userCmdMapHandler.put(Cmd.Logout.CMD,new LogoutHandler(userThreadMode.getUserCenter(), eventManager,
userFlagBusiness, userThreadMode.getUserResourceManager().getUserResourceCenter() ));
12.用户心跳处理器(用作示例:前端和后端如何通过cmd沟通)
//注册用户心跳的处理器
userCmdMapHandler.put(Cmd.Heartbeat.CMD,newHeartbeatHandler());
13.启动第8步实例化的用户退出处理线程
//启动用户退出检查线程
Thread userLogoutCheckRunnable= new Thread(userLogoutCheckBusiness);
userLogoutCheckRunnable.setName("userLogoutCheckRunnable");
userLogoutCheckRunnable.start();