?? 第二章 定位lookup service.htm
字號:
<html>
<head>
<title>新時代軟件教程:操作系統 主頁制作 服務器 設計軟件 網絡技術 編程語言 文字編輯</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<style>
<!--
body, table {font-size: 9pt; font-family: 宋體}
a {text-decoration:none}
a:hover {color: red;text-decoration:underline}
.1 {background-color: rgb(245,245,245)}
-->
</style>
</head>
<p align="center"><script src="../../1.js"></script></a>
<p align="center"><big><strong>第二章 定位Lookup Service</strong></big></p>
<p>客戶通過查詢某個Lookup Service來定位服務。為了實現這一點,首先必須找到lookup
service。另一方面,一個服務要在lookup service上注冊,首先也要找到lookup
service。所以客戶和服務的第一步都是要查找lookup service。查找lookup service有兩種方法:
unicast(唯一)和broadcast(廣播).
<P>1、一對一查找(Unicast discovery)<BR>當你已經知道了lookup
service所在的機器,就可以用一對一的查找。一般用在你知道lookup
service的準確地址。編程使用包net.jini.core.discovery中的類LookupLocator ,它有兩個構造函數如下:
<PRE><CODE>
package net.jini.core.discovery;
public Class LookupLocator {
LookupLocator(java.lang.String url)
throws java.net.MalformedURLException;
LookupLocator(java.lang.String host,int port);
}
</CODE></PRE>第一個構造函數中的URL必須是這種形式的 "jini://host/" 或者
"jini://host:port/"。如果不指定端口號(port),缺省端口是4160。下面的程序有一些有效或無效的host/URLs生成對象。
<PRE><CODE>
import net.jini.core.discovery.LookupLocator;
/**
* InvalidLookupLocator.java * *
* Created: Tue Mar 9 14:14:06 1999
* @author Jan Newmarch
* @version
*/
public class InvalidLookupLocator {
static public void main(String argv[]) {
new InvalidLookupLocator();
}
public InvalidLookupLocator() {
LookupLocator lookup; // this is valid
try {
lookup = new LookupLocator("jini://localhost");
System.out.println("First lookup creation succeeded");
} catch(java.net.MalformedURLException e) {
System.err.println("First lookup failed: " + e.toString()); }
// this is probably an invalid URL,
// but the URL is syntactically okay
try {
lookup = new LookupLocator("jini://ABCDEFG.org");
System.out.println("Second lookup creation succeeded");
} catch(java.net.MalformedURLException e) {
System.err.println("Second lookup failed: " + e.toString()); }
// this IS a malformed URL
try {
lookup = new LookupLocator("A:B:C://ABCDEFG.org");
System.out.println("Third lookup creation succeeded");
} catch(java.net.MalformedURLException e) {
System.err.println("Third lookup failed: " + e.toString()); }
// this is valid
lookup = new LookupLocator("localhost", 80);
System.out.println("Fourth lookup creation succeeded");
}
} // InvalidLookupLocator
</CODE></PRE>查找是通過類LookupLocator的方法getRegistrar()來實現的,該方法返回類
ServiceRegistrar的一個對象實例。
<PRE><CODE>
public ServiceRegistrar getRegistrar()
throws java.io.IOException,
java.lang.ClassNotFoundException
程序實例如下:
import net.jini.core.discovery.LookupLocator;
import net.jini.core.lookup.ServiceRegistrar;
/**
*UnicastRegistrar.java
* *
*Created: Fri Mar 12 22:34:53 1999
*
*@author Jan Newmarch
*@version
*/
public class UnicastRegistrar {
static public void main(String argv[])
{
new UnicastRegistrar(); }
public UnicastRegistrar() {
LookupLocator lookup = null;
ServiceRegistrar registrar = null;
try {
lookup = new LookupLocator("jini://localhost");
} catch(java.net.MalformedURLException e) {
System.err.println("Lookup failed: " + e.toString());
System.exit(1);
}
try { registrar = lookup.getRegistrar();
} catch (java.io.IOException e) {
System.err.println("Registrar search failed: " + e.toString());
System.exit(1);
} catch (java.lang.ClassNotFoundException e) {
System.err.println("Registrar search failed: " + e.toString());
System.exit(1); }
// the code takes separate routes from here for client or service }
} // UnicastRegistrar
</CODE></PRE>
<P>2、廣播式查找(Broadcast discovery)<BR>如果lookup
service的位置不知道,那就要用廣播式查找了。我們要使用在包net.jini.discovery 中的類LookupDiscovery
。它只有一個構造函數如下:
<PRE><CODE>
LookupDiscovery(java.lang.String[] groups)
</CODE></PRE>該構造函數的參數可以有三種不同的 情況:<BR>l、
null或LookupDiscovery.ALL_GROUPS,表示要找到所有可找到的lookup
service。<BR>2、一個空串或LookupDiscovery.NO_GROUPS,表示建立了對象,但是沒有執行查找。在這種情況下,為了執行查找需要調用方法setGroups()。<BR>3、一個非空的字符串,這樣就只查找該組的Lookup
Service.<BR>
<P>2.1 DiscoveryListener<BR>廣播式查找是在網上全面搜索,網上能收到信息的Lookup
Service都應該響應請求。這種查找是很費時間的,因為一般不知道能響應的lookup service的數目。為了處理這種不確定性,對象
LookupDiscovery可以注冊一個監聽器來監聽響應信息。
<PRE><CODE>
public void addDiscoveryListener(DiscoveryListener l)
該監聽器必須實現接口DiscoveryListener
package net.jini.discovery;public
abstract interface DiscoveryListener {
public void discovered(DiscoveryEvent e);
public void discarded(DiscoveryEvent e);
}
</CODE></PRE>不論什么時候,lookup
service一被發現就調用方法discovered()。API建議該方法應該立刻返回,不要做任何遠程調用。
而且對于服務方它可以很方便的注冊服務,而客戶也可以用它很方便的查找可用的服務,并調用該服務。該操作最好用一個單獨的線程來執行。其他問題包括:DiscoveryListener一建立,廣播就開始了。然后一個監聽器就加入該discovery對象中。如果在listener加入之前,有了響應會發生什么情況?規范保證這些響應會被存起來不會丟失。相反,如果長時間沒有響應來怎么辦?這不能簡單的退出,
只能等到有響應才行。處理方法只一,如果應用有GUI界面,可以由用戶停止;另一種方法是sleep 1000秒。當lookup
service放棄時,調用方法discarded()。
<P>2.2 DiscoveryEvent<BR>方法discover()的參數是DiscoveryEvent對象。
<PRE><CODE>
package net.jini.discovery;
public Class DiscoveryEvent {
public net.jini.core.lookup.ServiceRegistrar[] getRegistrars();
}
</CODE></PRE>它有一個公共方法getRegistrars(),該方法返回ServiceRegistrar對象數組。程序實例如下: <PRE><CODE>
import net.jini.discovery.LookupDiscovery;
import net.jini.discovery.DiscoveryListener;
import net.jini.discovery.DiscoveryEvent;
import net.jini.core.lookup.ServiceRegistrar;
/** * MulticastRegistrar.java * *
*Created: Fri Mar 12 22:49:33 1999
* @author Jan Newmarch
* @version
*/
public class MulticastRegistrar implements DiscoveryListener {
static public void main(String argv[]) {
new MulticastRegistrar();
}
public MulticastRegistrar() {
LookupDiscovery discover = null;
try {
discover = new LookupDiscovery(LookupDiscovery.ALL_GROUPS);
} catch(Exception e) {
System.err.println(e.toString());
System.exit(1);
}
discover.addDiscoveryListener(this);
// stay around long enough to receive replies
try {
Thread.currentThread().sleep(1000000L);
} catch(java.lang.InterruptedException e) {
// do nothing
}
}
public void discovered(DiscoveryEvent evt) {
ServiceRegistrar[] registrars = evt.getRegistrars();
for (int n = 0; n < registrars.length; n++) {
ServiceRegistrar registrar = registrars[n];
// the code takes separate routes from here for client or service }
}
public void discarded(DiscoveryEvent evt) { }
}// MulticastRegistrar
</CODE></PRE>
<P>3、ServiceRegistrar<BR>ServiceRegistrar是一個被每一個lookup
service實現的抽象類。該類實際實現的細節和這沒有關系。類ServiceRegistrar的作用是擔當lookup
service的代理。該代理運行在客戶或服務中。在Jini中,這是第一個從一個Java進程移到另一個進程中的對象。使用RMI,該對象被從lookup
service移到找到該lookup
service的應用中。從那時起,它就做為應用地址空間中的一個對象運行,同時該應用對它進行正常的方法調用。當需要的時候,它可以和它的lookup
service通信,但是這種通信不需要應用顯式的調用RMI方法。該對象有兩個主要的方法,其中一個是服務用來注冊的:
<PRE><CODE>public ServiceRegistration register(ServiceItem item,
long leaseDuration)
throws java.rmi.RemoteException
</CODE></PRE>另一個是客戶用來定位某個特定的服務:
<PRE><CODE>public java.lang.Object lookup(ServiceTemplate tmpl)
throws java.rmi.RemoteException;
public ServiceMatches lookup(ServiceTemplate tmpl,
int maxMatches)
throws java.rmi.RemoteException;
</CODE></PRE>一個服務要注冊一個對象(就是一個類的實例),和該對象的屬性集合。例如,打印機可以指定能否處理Postscript文檔。服務可以注冊本身,或注冊一個實現其行為的代理。注意:已注冊的對象可以通過RMI傳遞。最后當它運行時,可以離它開始建立的地方很遠。客戶使用所知道的一些服務特性來尋找服務。
</table>
<p align="center"><script src="../../2.js"></script></a>
</body>
</html>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -