远程访问mnemosyne
下面我们来讨论在servlet服务器上访问远程mnemosyne的方法。要在无需特定服务器在线的情况下加载一个包含对话信息的mnemosyne,需要创建一个failoverhandler的实例,failoverhandler利用jdk 1.3中的proxy api处理对话服务器当机的问题。failoverhandler把一个代表访问远程对话服务器的rmi url的字符串数组作为参数,然后,从proxy类中获取mnemosyne实例。下面的sessionmanager类中的initializemnemosyne()方法可以显示出这一切是如何完成的:
public static void initializemnemosyne(string[] rmiurls)
{
// 设置当机服务器的处理程序
failoverhandler fh = new failoverhandler(null, rmiurls);
// 得到mnemosyne. 的一个实例
_mnemosyne =
(mnemosyne)proxy.newproxyinstance(mnemosyne.class.getclassloader(),
new class[] { mnemosyne.class },
fh );
}
如果用proxy类获取mnemosyne的实例,所有的方法调用必须通过failoverhandler的 invoke()方法进行。当有方法访问mnemosyne时,failoverhandler将试着调用该方法访问一个远程对象。如果方法调用失败(例如服务器关机),failoverhandler将从提供给构造器的url清单中再取得下一个url,这样就会无缝地转向下一个对话服务器。
// 建立远程加载类的url清单
public failoverhandler(remote delegate, string[] delegateurls)
{
this.delegateurls = delegateurls;
// 如果这个url无效,则获取下一个有效的url
try {
this.delegate =
((delegate == null)?getnextvaliddelegate():delegate);
} catch (remoteexception ex) {
// 如果发生远程意外错误,则该url不能使用,向调用者发送一个 //illegalargumentexception事件
throw new illegalargumentexception("remote urls could not "
+ "be found");
}
}
public object invoke(object proxy,
method method,
object[] arguments)
throws throwable
{
while(true)
{
try
{
file:// 尝试对获得的最后一个url调用被调用的方法
return method.invoke(delegate, arguments);
}
catch(invocationtargetexception invocationtargetexception)
{
file://如果获得的url无效,则取下一个url
try
{
throw invocationtargetexception.gettargetexception();
}
catch(remoteexception remoteexception)
{
delegate = getnextvaliddelegate();
}
}
}
}
file://从构造器中的url清单中获得下一个url
protected remote getnextvaliddelegate() throws remoteexception
{
for(int i = 0; i < delegateurls.length;i++)
{
try
{
return naming.lookup(delegateurls[i]);
}
catch(exception exception)
{
}
}
throw new remoteexception("all lookup failed");
}
当使用failoverhandler对象时,从一个对话服务器向另一个对话服务器的转换对于调用mnemosyne的任何用户端机器都是透明的。
