The Elko Director Protocols
The Director
The Director is an Elko server that coordinates the operation of a collection of Context Servers. In particular, the Context Servers that a Director is working for keep it informed of their relative load factors, the opening and closing of contexts, the coming and going of users, and their availability for providing context services to arriving users.
The Director acts as a first contact point for users seeking entry to a particular context. Rather than contacting a Context Server directly, a user client instead contacts a Director (indeed, the client may not even know the network address of any Context Server). The client seeking entry informs the director of the ref of the context they wish to enter and the ref of the user as whom they wish to enter. The Director then checks to see if the requested context is already loaded on one of the Context Servers it knows about. If it is, the Director directs the user client to that Context Server. If it is not, the Director picks a suitable Context Server and requests it to open the desired context, and directs the user client to to this newly chosen Context Server. In either case, when the Director directs a client to a Context Server, it does not merely give the client the address of the Context Server, but also provides a reservation, an unguessable token that the Director also forwards to the chosen Context Server along with the context ref of the context being entered and the user ref of the user. When the client contacts the Context Server, it provides this reservation token along with its other entry credentials. The Context Server only permits a given client to enter a given context if it also provides the appropriate reservation token to do so. Reservations also expire after a short time (currently 30 seconds). This scheme allows the Director to act as a load balancer for a server farm full of Context Servers.
Since a Director keeps track of the active users on its collection of Context Servers, it can also enable users to rendezvous with each other, by directing a user to the appropriate context containing another user whom they wish to meet. This is especially important in highly scalable contexts, since context cloning may result in more than one instance of a particular context being active at any given time. The Director keeps track of which users are in which clone instances. In a similar vein, the Director can act as a message relay between users and contexts on different Context Servers.
Finally, since a Director is in contact with the entire collection of Context Servers, it can act as a centralized administration contact point for the server farm, enabling the whole farm or selected servers to be reinitialized, shutdown, or directed to take other specific actions.
A Director understands three different JSON message protocols. These correspond to the three kinds of actors who may wish to communicate with a Director: Context Servers providing context services, clients seeking reservations for entry into contexts, and administrators. Each of the ports that a Director listens for connections on can be configured to support any or all of these protocols.
Each of these protocols is associated with a particular object ref to which messages should be addressed:
director
for client messages requesting direction to Context Servers.provider
for Context Servers providing services.admin
for administrator messages.
Common Protocols
While there are three different message protocols, they share a common set of messages pertaining to connection housekeeping. These messages may be targeted at any of the three protocol objects described above.
auth
→ { to:REF, op:"auth", auth:?AUTHDESC, label:?STR}
This message begins a new session with the Director, providing whatever authorization credentials as may be appropriate (according to the Director's server configuration) to gain access to services.
An auth
message must be the first message sent
to director
, provider
, or admin
on any
new connection to the Director. Any other message to these objects will result
in immediate termination of the connection.
If the auth
operation fails, the connection will be terminated
by the Director. Otherwise, the client is thereafter free to send messages
according to the protocol of the REF
that was authorized.
auth
is a bundle of authorization information, as described below. The specific authorization information that is relevant depends on the configuration of the Director server port being connected to. If theauth
parameter is omitted, an uncontrolled access in open mode is assumed.label
is an optional label for the connection. This will be used in server log entries for debugging purposes and for identifying the connection in administrative requests.
Authorization information
The auth
parameter of the auth
message describes
a bundle of authorization information to authorize access. Its general form
is:
{ type:"auth", mode:STR, code:?STR, id:?STR }
where:
mode
is the requested authorization mode. Currently recognized authorization modes are"open"
and"password"
. Other modes may be relevant in the future or when talking to other kinds of servers.code
is an authorization code, whose meaning varies depending on the authorization mode. In the case of open mode, it is irrelevant and should not be provided. In the case of password mode, it is a password string.id
is an optional identity string, whose meaning varies depending on the authorization mode. In the case of open mode, it is irrelevant and should not be provided. In the case of password mode, it may or may not be relevant depending on the configuration.
disconnect
→ { to:REF, op:"disconnect" }
This message requests the server to terminate its connection to the sender. The connection to the server is broken.
ping
→ { to:REF, op:"ping", tag:?STR }
This message tests connectivity to the server.
tag
is an optional string that may be anything of the client's choosing.
If the message is successfully received by the server, it will reply with:
← { to:REF, op:"pong", tag:?STR }
tag
echoes the tag from theping
message, if there was one, or will be omitted if the originalping
also omitted it.
debug
→ { to:REF, op:"debug", msg:STR }
This message delivers debugging information to the server. If the server is
configured to permit this, the string given in the msg
parameter
will be written to the server's log. If the server is not configured to permit
this, this message will simply be ignored.
User Protocol
The Director user protocol is used by user clients requesting reservations for entry to contexts. There is only one message beyond the basic protocol:
reserve
→ { to:"director", op:"reserve", protocol:STR,
context:CONTEXTREF_STR, user:?USERREF_STR }
This message requests a reservation for entry into a context.
protocol
is the communications protocol by which the requestor wishes to communicate with the Context Server into which the requested context will be loaded. Valid values currently are"http"
,"tcp"
, or"rtcp"
.context
is the ref of the context into which entry is sought.user
is the optional ref of the user who is seeking entry. If omitted, the reservation being requested will be anonymous.
← { to:"director", op:"reserve", context:CONTEXTREF_STR,
user:?USERREF_STR, hostport:STR,
reservation:STR }
where:
context
is the ref of the context, which will match the corresponding parameter from the request.user
is the ref of the user, which will match the corresponding parameter from the request (and will be omitted if it was omitted from the request).hostport
is a string of the form"hostname:portnumber"
indicating the host name and port number of the Context Server on which the reservation has been made.reservation
is the reservation token to present to the Context Server in theentercontext
request to enter the context.
← { to:"director", op:"reserve", context:CONTEXTREF_STR,
user:?USERREF_STR, deny:STR }
where:
context
anduser
have the same meanings as in the success case.deny
is an error message string indicating why the reservation could not be made.
Provider Protocol
The Director provider protocol is used by providers of context services, that is, by Context Servers, to aprise the Director of their availability.
address
→ { to:"provider", op:"address", protocol:STR,
hostport:STR }
This message informs the Director of the sender's availability to speak some protocol at some network address.
where:
protocol
is a communications protocol that the sender speaks at the indicated address. Valid values currently are"tcp"
,"http"
, and"rtcp"
.hostport
is a string of the form"hostname:portnumber"
indicating the host name and port number at which the sender may be contacted using the indicated protocol.
context
→ { to:"provider", op:"context", context:CONTEXTREF_STR,
open:BOOL, yours:BOOL, maxcap:?INT,
basecap:?INT, restricted:?BOOL }
This message informs the Director of the opening or closing of a context by the sending Context Server.
where:
context
is the ref of the context that was opened or closed.open
is a flag that is true if the context was opened, false if it was closed.yours
is a flag that is true if this context was opened at the request of the Director to whom this message is being sent. This is used in a handshake to resolve a race condition that can happen if multiple different Directors concurrently request different Context Servers to open the same context. Note that this flag always indicates whether the recipient requested the opening of the context, regardless of whether this message is describing a context open or a context close.maxcap
indicates the maximum number of users that the Director should allow to be admitted to the context. This is only relevant on a context open. It is optional, and defaults to -1, meaning unlimited capacity, if omitted.basecap
indicates the maximum number of users that the Director should place in the context before directing a clone of the context to be opened instead. This is only relevant on a context open, and defaults to the value ofmaxcap
if omitted. A value of -1 indicates that the context should never be cloned.restricted
is a flag that is true if the context is restricted. A restricted context is one that users (clients authorized to send messages to"user"
may not request a reservation for (though context servers themselves may). This is only relevant on a context open.
It is optional and defaults to false, meaning unrestricted, if omitted.
load
→ { to:"provider", op:"load", factor:FLOAT }
This message informs the Director of sender's current load.
where:
factor
is sender's current load factor. This may be any value, though all Context Servers talking to a given Director should all share a single, commensurable metric.
relay
→ { to:"provider", op:"relay", context:?CONTEXTREF_STR,
user:?USERREF_STR, msg:JSONOBJ }
This message requests the Director to relay a message to a user or context on a different Context Server from the sender.
where:
context
is the ref of the context to relay the message to.user
is the ref of the user to relay the message to.msg
is the message to relay.
context
and user
parameters are mutually
exclusive, and one or the other must be provided. If the base ref of a cloned
context or user is specified, the message will be relayed to all Context
Servers (other than the sender) who host clones of the indicated recipient
context or user.
The relay
message will result in the corresponding
relay
message being sent to all relevant Context Servers (i.e.,
those serving the context or user indicated). It takes the same form as the
inbound request:
← { to:"provider", op:"relay", context:?CONTEXTREF_STR,
user:?USERREF_STR, msg:JSONOBJ }
user
→ { to:"provider", op:"user", context:CONTEXTREF_STR,
user:USERREF_STR, on:BOOL }
This message informs the Director of the entry or exit of a user to or from a context hosted by the sender.
where:
context
is the ref of the context that the user entered or exited.user
is the ref of the user who entered or exited.on
is a flag that is true the user entered, false if the user exited.
willserve
→ { to:"provider", op:"willserve", context:STR,
capacity:?INT }
This message informs the Director of the sender's availability to serve some family of contexts.
where:
context
is the ref prefix of the family of contexts that the sender is prepared to serve. Typically this is the string"context"
, but that is not mandatory.capacity
is an optional limit on the maximum number of user clients that the sender is willing to serve for the indicated class of contexts. If omitted, it defaults to -1, indicating no limit.
close
This message may be sent by the Director to the Context Server. It instructs the Context Server to force the closure of a context or the disconnection of a user.
← { to:"provider", op:"close", context:?CONTEXTREF_STR,
user:?USERREF_STR, dup:?BOOL }
where:
context
is the ref of the context to close.user
is the ref of the user to disconnect.dup
is true if the context closure or user disconnection is requested as part of the Director resolving a duplicated context open.
The context
and user
parameters are mutually
exclusive.
reinit
This message may be sent by the Director to the Context Server. It instructs the Context Server to reinitialize itself.
← { to:"provider", op:"reinit" }
shutdown
This message may be sent by the Director to the Context Server. It instructs the Context Server to shut itself down.
← { to:"provider", op:"shutdown", kill:?BOOL }
where:
kill
is an optional flag that if true orders an abrupt termination of the Context Server. Normally, the server would empty its message queue, checkpoint any active state, and perform an orderly shutdown. However, if thekill
flag is true, it will exit immediately without stopping to clean things up. The value defaults to false if the parameter is omitted.
say
This message may be sent by the Director to the Context Server. It requests the Context Server to deliver asay
message to a particular user or to
the users in a particular context.
← { to:"provider", op:"say", context:?CONTEXTREF_STR,
user:?USERREF_STR, text:STR }
where:
context
is the ref of a context being spoken to.user
is the ref of a user being spoken to.text
is speech text directed at the indicated context or user.
context
and user
parameters are mutually
exclusive, and one or the other must be provided. If the base ref of a cloned
context or user is specified, all clones of the indicated context or user will
be spoken to.
Admin Protocol
The Director admin protocol is used to administer the Director and, indirectly, the entire collection of Context Servers it is in contact with.
close
→ { to:"admin", op:"close", context:?CONTEXTREF_STR,
user:?USERREF_STR }
This message instructs the Director to force the closure of a context or the disconnection of a user.
where:
context
is the ref of the context to close.user
is the ref of the user to disconnect.
context
and user
parameters are mutually
exclusive, and one or the other must be provided. If the base ref of a cloned
context or user is specified, all clones of the indicated context or user will
be closed.
If the indicated context is open or the indicated user is connected, the
Director will send a provider close
message to each relevant
connected Context Server instructing it to take the requested action.
dump
→ { to:"admin", op:"dump", depth:INT, provider:?STR,
context:?CONTEXTREF_STR }
This message requests the Director to provide a dump of its state to the requesting administrator.
where:
depth
indicates the depth of detail to provide (see below).provider
optionally limits the scope of the information dumped to providers matching the parameter string. This is matched against the label string provided in theauth
message that providers sent when they connected to the Director.context
optionally limits the scope of the information dumped to contexts matching the parameter string.
← { to:"admin", op:"dump", numproviders:INT,
numcontexts:INT, numusers:INT,
providers:[PROVIDERDUMP] }
where:
numproviders
is the number of providers, currently connected to the Director and providing context services, that are described by this dump.numcontexts
is the number of open contexts that are described by this dump.numusers
is the number of connected users that are described by this dump.providers
is an array of provider dump descriptors, each of which describes one provider. This will only be provided if the value of thedepth
parameter was greater than 0.
{ type:"providerdesc", provider:STR, numcontexts:INT,
numusers:INT, load:FLOAT, capacity:INT,
hostports:[STR], protocols:[STR], serving:[STR],
contexts:[OPENCONTEXTDUMP] }
where:
provider
is the label that the provider gave for itself in theauth
message with which it connected to the Director.numcontexts
is the number of open contexts currently being served by this provider.numusers
is the number of connected users currently being served by this provider.load
is this provider's current load factor.capacity
is number of user clients this provider is willing to serve.hostports
is an array of"hostname:portnumber"
strings listing all the ports at which the provider is providing context services.protocols
is an array of strings, parallel tohostports
, indicating the protocol spoken at the correspondinghostports
entry. The value of each element of this array will be either"tcp"
or"http"
.serving
is an array of strings listing the context families that the provider is willing to serve.contexts
is an array of context dump descriptors, each of which describes one open context. This will only be provided if the value of thedepth
parameter was greater than 1.
{ type:"contextdesc", context:CONTEXTREF_STR, numusers:INT,
users:[USERREF_STR] }
where:
context
is ref of the open context.numusers
is the number of users currently in the context.users
is an array of the refs of the users currently in the context. This will only be provided if the value of thedepth
parameter was greater than 2.
find
→ { to:"admin", op:"find", context:?CONTEXTREF_STR,
user:?USERREF_STR }
This message requests the Director to provide the location of a context or user.
where:
context
is the ref of the context whose location is sought.user
is the ref of the user whose location is sought.
context
and user
parameters are mutually
exclusive, and one or the other must be provided. If the base ref of a cloned
context or user is specified, the locations of all clones of the indicated
context or user will be returned.
If a context location was requested, the Director will reply with:
← { to:"admin", op:"context", context:?CONTEXTREF_STR,
open:BOOL, provider:?STR,
clones:[CONTEXTREF_STR] }
where:
context
is the ref of the context that was inquired about.open
is true if the the context is open, on one of the Director's provider Context Servers, false if not.provider
is the label of the provider on which the context is open, it is open. This field is absent if the context is not open.clones
is an optional array of context refs of open clones of the context, if the context is cloned (note that in such a case,open
will be false).
If a user location was requested, the Director will reply with:
← { to:"admin", op:"user", user:?USERREF_STR, on:BOOL,
contexts:[CONTEXTREF_STR] }
where:
user
is the ref of the user that was inquired about.on
is true if the the user is connected to one of the Director's provider Context Servers, false if not.contexts
is an array of context refs of all open contexts that the user is in. This will be provided only if the user has entered at least one context.
listcontexts
→ { to:"admin", op:"listcontexts" }
This message requests the Director to provide a list of currently open contexts.
The Director will reply with:
← { to:"admin", op:"listcontexts", contexts:[CONTEXTREF_STR] }
where:
contexts
is an array of context refs of open contexts.
listproviders
→ { to:"admin", op:"listproviders" }
This message requests the Director to provide a list of known providers (i.e., Context Servers).
The Director will reply with:
← { to:"admin", op:"listproviders", providers:[STR] }
where:
providers
is an array of the labels of providers currently connected to the Director.
listusers
→ { to:"admin", op:"listusers" }
This message requests the Director to provide a list of currently connected users.
The Director will reply with:
← { to:"admin", op:"listusers", users:[USERREF_STR] }
where:
users
is an array of users refs of connected users.
reinit
→ { to:"admin", op:"reinit", provider:?STR,
director:?BOOL }
This message instructs the Director to reinitialize one or more servers.
where:
provider
is the optional label for a provider to be reinitialized. Alternatively, the string"all"
indicates that all providers are to be reinitialized. If omitted, no providers will be reinitialized.director
is an optional flag that if true directs that the Director itself also be reinitialized. The value defaults to false if the parameter is omitted. Director reinitialization, if requested, will take place after any provider reinitializations.
reinit
message on its provider connection.
relay
→ { to:"admin", op:"relay", context:?CONTEXTREF_STR,
user:?USERREF_STR, msg:JSONOBJ }
This message requests the Director to relay a message to a user or context
on whatever Context Server is appropriate. It takes the exact same form and
has the same behavior as the corresponding message in the provider protocol,
except of course that it is targeted at "admin"
instead of
"provider"
.
say
→ { to:"admin", op:"say", context:?CONTEXTREF_STR,
user:?USERREF_STR, text:STR }
This message requests the Director to deliver a say
message to
a particular user or to the users in a particular context.
where:
context
is the ref of a context being spoken to.user
is the ref of a user being spoken to.text
is speech text directed at the indicated context or user.
context
and user
parameters are mutually
exclusive, and one or the other must be provided. If the base ref of a cloned
context or user is specified, all clones of the indicated context or user will
be spoken to.
The Director will send a corresponding say
message to each
relevant Context Server.
shutdown
→ { to:"admin", op:"shutdown", provider:?STR,
director:?BOOL, kill:?BOOL }
This message instructs the Director to shut down one or more servers.
where:
provider
is the optional label for a provider to be shut down. Alternatively, the string"all"
indicates that all providers are to be shut down. If omitted, no providers will be shut down.director
is an optional flag that if true directs that the Director itself also be shut down. The value defaults to false if the parameter is omitted. Director shutdown, if requested, will take place after any provider shutdowns.kill
is an optional flag that if true orders an abrupt termination of the indicated server(s). Normally, servers will empty their message queues, checkpoint any active state, and perform an orderly shutdown. However, if thekill
flag is true, they will exit immediately without stopping to clean things up. The value defaults to false if the parameter is omitted.
shutdown
message on its provider connection.
watch
→ { to:"admin", op:"watch", context:?CONTEXTREF_STR,
user:?USERREF_STR }
This message requests the Director to begin providing ongoing updates as to the location of a context or user.
where:
context
is the ref of the context of interest.user
is the ref of the user of interest.
context
and user
parameters are mutually
exclusive, and one or the other must be provided. If the base ref of a cloned
context or user is specified, the locations of all clones of the indicated
context or user will be watched.
The operation of watch
is similar to find
, except
that the Director maintains continuous surveillance of the context or user
indicated. Each time the context is opened or close, or the user enters or
exits, a context
or user
message will be sent to the
administrator. These messages take the same form as they do in the replies to
the find
request; the only difference is that the behavior is
spontaneous and asynchronous.
unwatch
→ { to:"admin", op:"unwatch", context:?CONTEXTREF_STR,
user:?USERREF_STR }
This message requests the Director to cease providing ongoing updates as to
the location of a context or user. It undoes the effect of an earlier
watch
request.
where:
context
is the ref of the context of interest.user
is the ref of the user of interest.
context
and user
parameters are mutually
exclusive, and one or the other must be provided. For this request to be
useful, the parameters should match those of an earlier watch
request. However, requesting an unwatch
of a context or user that
was not actually being watched is a benign operation with no effect.