# 4 An Example of a Server Directory

### Andreas Sundström

This contribution is meant primarily to work as an example of how one can use the module `Discovery` and build a yellow pages service. The directory service consists out of three parts: a directory server, an interface to announce services, and a way to find announced services.

All services have descriptions. When a lookup is performed, a pattern is given to specify what to look for. The result of the lookup are services that have descriptions matching the pattern. Both descriptions and patterns are Oz records.

So what does it mean that a description match a pattern? All features in a pattern must be present in the description. If a field in the pattern has a value, then it must be either equal or match to a corresponding field in the description. For example, f(a:1 b:g(x:5 y:7) c:28 d:foo) does match f(c:28 b:g d:_), but not the other way around.

One could say that a pattern puts constraints on a matching description. Our form of pattern puts constraints on the label and features of the description.

## 4.1 The ExampleDirectory Module

The module has three classes under features (`server`, `serviceProvider` and `client`), which corresponds to the three parts mentioned earlier.

The class `ExampleDirectory.server` has following methods:

`init`

  > > `init(port:``PortNr``<= useDefault
  > > expectedClientId:``ClientId``<= unit
  > > id:``ServerId``<= directory(kind:recordMatching))
  > > `

  This method starts a directory server. The initial contact between a client (or service provider) and the server is made through the ip port `PortNr`. The default ip port number is `Discovery.defaultPortNumber`. After the first contact has been performed, all subsequent interactions are done using Oz ports.

  `ServerId` is a record explaining which type of directory server it is.

  `ClientId` is a record used to specify which clients should be served. If a client id sent from a client (or service provider) matches `ClientId`, the client will be served. If the feature `expectedClientId` is not specified the server will serve every client requesting service.

`close`

  > > `close()
  > > `

  Closes the operation of the server.

The class `ExampleDirectory.serviceProvider` has following methods:

`init`

  > > `init(serverPort:``PortNr``<= useDefault
  > > id:``ClientId``<= unit
  > > expectedServerId:``ServerId``<= directory(kind:recordMatching)
  > > timeOut:``TimeOut``<= 1000)
  > > `

  This method broadcasts to the ip port `PortNr` and waits for answers from servers that listen to it. The servers that answer and which id matches `ServerId` will be used by the other methods of this class.

  When interacting with the servers, `ClientId` will be used as identification. The method will not consider answers received after `TimeOut` milliseconds has gone by.

`add`

  > > `add(description:``Desc``
  > > ticket:``Ticket``
  > > key:?``Key <= _``)
  > > `

  This method announces a service with a description `Desc`. `Ticket` is a ticket to an Oz-entity that is used as an interface to the service. An Oz name that can be used to remove the service from the directories is returned.

`remove`

  > > `remove(key:Key)`

  Tells the servers to remove a service with the key `Key`.

The class `ExampleDirectory.client` has following methods:

`init`

  > > `init(serverPort:``PortNr``<= useDefault
  > > id:``ClientId``<= unit
  > > expectedServerId:``ServerId``<= directory(kind:recordMatching)
  > > timeOut:``TimeOut``<= 1000)
  > > `

  Similar to `ExampleDirectory.serviceProvider`.

`lookup`

  > > `lookup(pattern:``Pattern` `services:?``Services``)
  > > `

  Asks servers for services that match the `Pattern`. A list of pairs is returned. Those pairs consist of a service description and its ticket.