2.4.3 初始化
备份chatserver目录下的service-chatserver.xml文件,然后重新ant生成一个service-chatserver.xml作一比较。
结果可以发现发布版本的Provider element中多出两个属性。
className="chat.chatserver.SessionManager"
classSingleton="getInstance"
这就是初始化入口,实际上SessionManager继承自ProviderListener,也就是说必须提供给系统提供一个ProviderListener对象用于Provider交互,提供的方式是通过getInstance方式获取一个单件,如果没有这一属性,系统就通过new chat.chatserver.SessionManager()的方式获得。
一般来说,实现自己的服务的时候,必须自己实现一个ProviderListener,然后修改配置文件。
SessionManager.java:
private void openListen() {
try {
manager.openListen();
} catch (IOException e) {
if (Trace.isErrorEnabled())
Trace.error("SessionManager.openListen", e);
getManager().close();
}
}
public void onManagerInitialized(Manager manager, Config config) {
this.manager = (ServerManager) manager;
......................
if (table.Hallnamecache.get().getCacheSize() == 0)
GlobalId.runOnValidation(() -> {
insertDefaultChatrooms();
openListen();
});
else {
setViewHallsFromCache();
openListen();
}
}
系统内部初始化完成以后,首先调用onManagerInitialized方法, 通知Provider进行初始化。初始化主要两个步骤, 首先准备好Provider所需的资源, 接着通过调用openListen, 通知switcher服务器Provider准备就绪,允许客户端接入。
在这里,Provider准备资源有两种形式,数据库中聊天室存在的情况下setViewHallsFromCache加载聊天室配置信息, 不存在则创建默认聊天室。因为创建聊天室依赖GlobalId服务器维护名字, 默认聊天室的创建必须成功, 所以通过GlobalId.runOnValidation提交一个任务, 确保GlobalId服务器连接成功后执行。
注意,GlobalId.runOnValidation提交的任务在Engine的应用线程池中执行,如果执行过程中因为GlobalId服务器的原因失败抛出GlobalId.Exception, 比如连接断开,那么应该考虑重新调度的问题。
要使用GlobalId服务,需要正确配置:
service-chatserver.xml:
<GlobalId autoReconnect="true" remoteIp="127.0.0.1" remotePort="10210"/>
SessionManager.java:
public void onManagerUninitialized(Manager manager) {
}
Provider服务终止时调用该方法,在这里释放Provider分配的资源。
SessionManager.java:
public void onTransportAdded(Transport transport) throws Exception {
if (Trace.isInfoEnabled())
Trace.info("onTransportAdded " + transport);
}
用户上线,用户相关的View资源初始化完毕后这个方法被调用。
SessionManager.java:
public void onTransportRemoved(Transport transport) throws Exception {
if (Trace.isInfoEnabled())
Trace.info("onTransportRemoved " + transport);
}
用户离线,用户相关的View资源释放完毕以后这个方法被挑用。
SessionManager.java:
public void onTransportDuplicate(Transport transport) throws Exception {
if (Trace.isInfoEnabled())
Trace.info("onTransportDuplicate " + transport);
manager.close(transport);
}
这一方法报告用户重复登录的情况,给处理重复登录留下决策空间。这里的transport参数是用户前一个session的transport。关闭这个transport或者抛出异常,则前一个session被踢掉,后一个session可以登录上线,如果这个方法什么都不做,则后续session被阻止,禁止了重复登录。