Suchen Sie Dienste mit dem Jini-Suchdienst

Der Jini-Suchdienst, die zentrale Komponente der Laufzeitinfrastruktur von Jini, bietet Jini-Clients eine flexible und leistungsstarke Möglichkeit, Jini-Dienste zu finden. Es ermöglicht Dienstanbietern, für ihre Dienste zu werben, und ermöglicht es Kunden, die Hilfe dieser Dienste zu finden und in Anspruch zu nehmen.

Um mit dem Suchdienst zu interagieren, muss der Client zunächst ein Dienstregistrierungsobjekt über Discovery abrufen , ein Protokoll auf Netzwerkebene, das von Jinis Laufzeitinfrastruktur verwendet wird. Mit Discovery können Clients und Dienste Suchdienste suchen. (Weitere Informationen zur Ermittlung finden Sie unter Ressourcen.) Das service registrarObjekt, das die net.jini.core.lookup.ServiceRegistrarSchnittstelle implementiert , ermöglicht dem Client die Interaktion mit dem Suchdienst. Um die gewünschten Dienste zu finden, erstellen Clients eine ServiceTemplateKlasseninstanz net.jini.core.lookup.ServiceTemplateund übergeben sie an eine von zwei lookup()in der ServiceRegistrarSchnittstelle deklarierten Methoden . Jede lookup()Methode sendet die Dienstvorlage an den Suchdienst, der die Abfrage ausführt und übereinstimmende Dienstobjekte an den Client zurückgibt.

Im Allgemeinen sucht ein Client einen Dienst nach Java-Typ, normalerweise eine Schnittstelle. Wenn ein Client beispielsweise einen Drucker verwenden muss, erstellt er eine Dienstvorlage, die ein ClassObjekt für eine bekannte Schnittstelle zu Druckerdiensten enthält. Alle Druckerdienste implementieren die Schnittstelle. Der Suchdienst gibt ein Dienstobjekt (oder Objekte) zurück, die diese Schnittstelle implementieren. Sie können Attribute in die Servicevorlage aufnehmen, um die Anzahl der Übereinstimmungen für eine solche typbasierte Suche einzugrenzen. Der Client verwendet den Druckerdienst, indem er für das Dienstobjekt die in der bekannten Schnittstelle deklarierten Methoden aufruft.

Die ServiceTemplate-Klasse

Mit der ServiceTemplateKlasse können Sie die Suchkriterien für Jini-Lookups ausdrücken. Die Klasse besteht ausschließlich aus diesen drei öffentlichen Feldern:

public Entry [] attributeSetTemplates; public ServiceID serviceID; public Class [] serviceTypes;

ServiceTemplatehat keine Methoden und seine Instanzen dienen lediglich als "struct" -ähnliche Container für Suchdienstabfragen. Übereinstimmungen werden wie im folgenden Auszug auf ServiceTemplateder Javadoc-Seite beschrieben durchgeführt:

Elemente im Suchdienst werden mit einer Instanz von [ ServiceTemplate] abgeglichen . Ein Serviceelement ( item) entspricht einer Servicevorlage ( tmpl), wenn:

  • item.serviceIDgleich tmpl.serviceID(oder wenn tmpl.serviceIDist null)
  • item.service [das Serviceobjekt] ist eine Instanz jedes Typs in tmpl.serviceTypes
  • item.attributeSets enthält mindestens einen passenden Eintrag für jede Eintragsvorlage in tmpl.attributeSetTemplates

Ein Eintrag stimmt mit einer Eintragsvorlage überein, wenn die Klasse der Vorlage mit der Klasse des Eintrags identisch ist oder eine Oberklasse davon ist und jedes Nicht-Null-Feld in der Vorlage dem entsprechenden Feld des Eintrags entspricht. Jeder Eintrag kann verwendet werden, um mehr als eine Vorlage abzugleichen. Beachten Sie, dass in einer Dienstvorlage für serviceTypesund attributeSetTemplatesein Nullfeld einem leeren Array entspricht. beide repräsentieren einen Platzhalter.

Wie hier beschrieben, kann die Dienstvorlage einen Verweis auf ein Array von ClassObjekten enthalten. Diese Objekte geben dem Suchdienst den Java-Typ (oder die Java-Typen) des vom Client gewünschten Dienstobjekts an. Die Dienstvorlage kann auch eine Dienst-ID enthalten, die einen Dienst eindeutig identifiziert, sowie Attribute, die genau mit den Attributen übereinstimmen müssen, die vom Dienstanbieter in das Dienstelement hochgeladen wurden. Die Servicevorlage kann auch Platzhalter für eines dieser Felder enthalten. Ein Platzhalter im Feld Service-ID stimmt beispielsweise mit jeder Service-ID überein.

Die lookup () -Methoden

Die ServiceRegistrar‚s lookup()Methoden nehmen zwei überladene Formen. Die beiden Formulare unterscheiden sich hauptsächlich in der Anzahl der Übereinstimmungen und Serviceelemente, die jeweils zurückgegeben werden. Das Zwei-Parameter-Formular kann mehrere Übereinstimmungen der in der angegebenen Abfrage zurückgeben ServiceTemplate, während das Ein-Parameter-Formular nur eine Übereinstimmung zurückgibt. Darüber hinaus gibt das Zwei-Parameter-Formular ganze Serviceelemente zurück. Das Ein-Parameter-Formular gibt nur das Serviceobjekt zurück.

Die Zwei-Parameter-Form von lookup ()

Hier ist ein Javadoc-Auszug, der die Zwei-Parameter-Form von erklärt lookup():

Die Suche nach öffentlichen ServiceMatches (ServiceTemplate tmpl, int maxMatches) löst java.rmi.RemoteException aus. 

[Es] gibt höchstens maxMatchesElemente zurück, die mit der Vorlage übereinstimmen, sowie die Gesamtzahl der Elemente, die mit der Vorlage übereinstimmen. Der Rückgabewert ist nie null, und das Array für zurückgegebene Elemente ist nur nulldann gültig, wenn maxMatcheses Null ist. Wenn das Serviceobjekt für jedes zurückgegebene Element nicht deserialisiert werden kann, wird das Servicefeld des Elements auf gesetzt nullund keine Ausnahme ausgelöst. Wenn ein Attributsatz nicht deserialisiert werden kann, wird dieses Element des attributeSetsArrays auf gesetzt nullund es wird keine Ausnahme ausgelöst.

Hier ist die ServiceMatchesKlasse:

Paket net.jini.core.lookup;

public class ServiceMatches erweitert java.lang.Object implementiert java.io.Serializable {

public ServiceItem [] items; public int totalMatches; }}

Und hier ist die ServiceItemKlasse:

Paket net.jini.core.lookup;

public class ServiceMatches erweitert java.lang.Object implementiert java.io.Serializable {

public Entry [] attributeSets; öffentlicher java.lang.Object-Dienst; public ServiceID serviceID; }}

Wie bereits erwähnt, ist jedes Element des itemsArrays, das vom Zwei-Parameter-Formular zurückgegeben wird, ein vollständiges Serviceelement, das das Serviceobjekt, die Service-ID und alle Attributgruppen enthält. Das maxMatchesFeld hilft Clients bei der Verwaltung der Anzahl der von diesem zurückgegebenen Objekte lookup().

Die Länge des itemsArrays im zurückgegebenen ServiceMatchesObjekt ist kleiner oder gleich dem Wert, der an lookup()in übergeben wird maxMatches. Die Gesamtzahl der übereinstimmenden Serviceelemente (zurückgegeben in totalMatches) ist größer oder gleich der Länge des itemsArrays.

Wenn beispielsweise maxMatches50 ist und die Dienstvorlage mit 25 Elementen itemsübereinstimmt, totalMatchessind sowohl die Länge des zurückgegebenen Arrays als auch der Wert von 25. Wenn maxMatchesdie Dienstvorlage 50 ist, die Dienstvorlage jedoch mit 100 Elementen übereinstimmt, beträgt die Länge des zurückgegebenen itemsArrays 50 und Der Wert totalMatchesist 100. Wenn eine Servicevorlage mit mehr als maxMatchesServiceelementen übereinstimmt , werden die vom Zwei-Parameter zurückgegebenen lookup()Serviceelemente zufällig aus dem vollständigen Satz übereinstimmender Serviceelemente ausgewählt.

Die Ein-Parameter-Form von lookup ()

Die Ein-Parameter- lookup()Methode gibt ein übereinstimmendes Serviceobjekt zurück, das zufällig aus allen Übereinstimmungen ausgewählt wurde. Hier ist ein Javadoc-Auszug, der dieses Formular erklärt:

public Object Lookup (ServiceTemplate tmpl) löst java.rmi.RemoteException aus; 
Gibt das Serviceobjekt (dh nur ServiceItem.service) von einem Element zurück, das mit der Vorlage übereinstimmt, oder nullwenn keine Übereinstimmung vorliegt. Wenn mehrere Elemente mit der Vorlage übereinstimmen, ist es beliebig, welches Serviceobjekt zurückgegeben wird. Wenn das zurückgegebene Objekt nicht deserialisiert werden kann, wird ein Objekt UnmarshalExceptionmit der Standard-RMI-Semantik ausgelöst.

Da der Ein-Parameter lookup()nur ein übereinstimmendes Serviceobjekt zurückgibt, können Clients die Anzahl der heruntergeladenen Objektstatus- und Klassendateien minimieren. Da das zurückgegebene Serviceobjekt jedoch willkürlich ausgewählt und nicht durch eine Service-ID identifiziert oder durch zugehörige Attributgruppen beschrieben wird, muss der Client sicher sein, dass ein übereinstimmendes Serviceobjekt ausreicht.

Die Browsing-Methoden

In addition to the two lookup() methods, the ServiceRegistrar has three browsing methods, which yield information about registered service items. The three methods -- getServiceTypes(), getEntryClasses(), and getFieldValues() -- are called browsing methods because they enable clients to browse the services and attributes in the lookup service.

The getServiceTypes() method takes a ServiceTemplate (the same ServiceTemplate that is passed to the lookup() methods) and a String prefix. It returns an array of Class instances representing the most specific types (classes or interfaces) of the service objects that match the template. These service objects are neither equal to, nor a superclass of, any of the types specified in the template, and they have names that start with the specified prefix. The service object or objects for which Class instances are returned are all instances of all the types (if any) passed in the template, but the Class instances are all more specific than (and are subclasses or subinterfaces of) those types. Each class appears only once in the returned array, and in arbitrary order.

Here's what getServiceTypes() looks like:

public java.lang.Class[] getServiceTypes(ServiceTemplate tmpl, java.lang.String prefix) throws java.rmi.RemoteException; 

The getEntryTypes() method takes a ServiceTemplate and returns an array of Class instances that represent the most specific classes of entries for the service items that match the template, which either don't match any entry template or are a subclass of one. Each class appears only once in the returned array, again in arbitrary order.

Here's what getEntryClasses() looks like:

public java.lang.Class[] getEntryClasses(ServiceTemplate tmpl) throws java.rmi.RemoteException; 

The getFieldValues() method takes a ServiceTemplate, an integer index, and a String field name. It returns an array of Objects for the named field of all instances of the entry that appears in the ServiceTemplate's Entry[] array at any matching service item's passed index. Each object of a particular class and value appears only once in the returned array, and in arbitrary order.

Here's what getFieldValues() looks like:

public java.lang.Object[] getFieldValues(ServiceTemplate tmpl, int setIndex, java.lang.String field) throws java.lang.NoSuchFieldException, java.rmi.RemoteException; 

The behavior and purpose of these browsing methods can be obscure. You might think of them as tools that incrementally narrow queries of the lookup service.

For example, a client such as a graphical lookup service browser could first invoke getServiceTypes() with an empty template. The getServiceTemplate() method returns all possible service types registered in the lookup service, which the browser could display. The user could select one or more types, then push the Requery button. The browser would add that type (or types) to the service template and invoke getServiceTypes() again. A smaller list of types would be returned and displayed by the browser. The user could select one and press an Entries button. The browser would form a template with the most recently selected service type or types, and then invoke getEntryTypes(). The getEntryTypes() method would return an array of entry classes, which the browser could then display.

The user could select some entries -- and a field of a selected entry -- and push a Fields button. The browser would build a template using the currently selected service and entry types. It would then pass the index of the entry class in which the user selected the field, and the name of the selected field, to getFieldValues(). The browser would display all the values that getFieldValues() returned. With those values the user could further narrow the search for a service, eventually choosing a particular service. Thus, these methods help clients, whether or not a human user is involved, to browse the services registered in a lookup service. The arrays returned from the browsing methods can help the client further refine its queries, ultimately resulting in a ServiceTemplate that, when passed to lookup(), returns the most appropriate service object.

The notify() method

In addition to the lookup and browsing methods, the ServiceRegistrar interface also has a notify() method that notifies clients when new services register or unregister with a lookup service:

public EventRegistration notify(ServiceTemplate tmpl, int transitions, RemoteEventListener listener, MarshalledObject handback, long leaseDuration) throws RemoteException; 

You invoke notify() to register yourself (or another listener) to receive a distributed event whenever the services that match the passed ServiceTemplate undergo a state change described by the transitions parameter.

The transitions parameter is a bitwise OR of any nonempty set of these three values, defined as constants in ServiceRegistrar:

TRANSITION_MATCH_MATCH TRANSITION_MATCH_NOMATCH TRANSITION_NOMATCH_MATCH 

You build the ServiceTemplate for notify() in the same way you build it for lookup(). You can indicate explicit types, a service ID, attributes (which must exactly match), or wild cards (which match anything) in any of those fields. The transitions are based on a change (or nonchange) in the status of whatever matches your ServiceTemplate before and after any operation is performed on the lookup service.

Gibt beispielsweise an, TRANSITION_MATCH_MATCHdass mindestens ein Serviceelement vor und nach einem Vorgang mit Ihrer Vorlage übereinstimmt. TRANSITION_MATCH_NOMATCHGibt an, dass mindestens ein bestimmtes Serviceelement vor einem Vorgang mit Ihrer Vorlage übereinstimmte, nach dem Vorgang jedoch nicht mehr mit Ihrer Vorlage. Um eine Benachrichtigung zu erhalten, wenn neue Dienste zu einem Suchdienst hinzugefügt werden, geben Sie einfach eine Vorlage an, die mit jedem Dienst übereinstimmt, und übergeben sie TRANSITION_NOMATCH_MATCHals Übergang zur notify()Methode.

SUBHEAD_BREAK: Suchdienst versus Nameserver