遠程訪問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的任何用戶端機器都是透明的。
|