250 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
			
		
		
	
	
			250 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
========
 | 
						|
Presence
 | 
						|
========
 | 
						|
 | 
						|
A description of presence information and visibility between users.
 | 
						|
 | 
						|
Overview
 | 
						|
========
 | 
						|
 | 
						|
Each user has the concept of Presence information. This encodes a sense of the
 | 
						|
"availability" of that user, suitable for display on other user's clients.
 | 
						|
 | 
						|
 | 
						|
Presence Information
 | 
						|
====================
 | 
						|
 | 
						|
The basic piece of presence information is an enumeration of a small set of
 | 
						|
state; such as "free to chat", "online", "busy", or "offline". The default state
 | 
						|
unless the user changes it is "online". Lower states suggest some amount of
 | 
						|
decreased availability from normal, which might have some client-side effect
 | 
						|
like muting notification sounds and suggests to other users not to bother them
 | 
						|
unless it is urgent. Equally, the "free to chat" state exists to let the user
 | 
						|
announce their general willingness to receive messages moreso than default.
 | 
						|
 | 
						|
Home servers should also allow a user to set their state as "hidden" - a state
 | 
						|
which behaves as offline, but allows the user to see the client state anyway and
 | 
						|
generally interact with client features such as reading message history or
 | 
						|
accessing contacts in the address book.
 | 
						|
 | 
						|
This basic state field applies to the user as a whole, regardless of how many
 | 
						|
client devices they have connected. The home server should synchronise this
 | 
						|
status choice among multiple devices to ensure the user gets a consistent
 | 
						|
experience.
 | 
						|
 | 
						|
Idle Time
 | 
						|
---------
 | 
						|
 | 
						|
As well as the basic state field, the presence information can also show a sense
 | 
						|
of an "idle timer". This should be maintained individually by the user's
 | 
						|
clients, and the homeserver can take the highest reported time as that to
 | 
						|
report. Likely this should be presented in fairly coarse granularity; possibly
 | 
						|
being limited to letting the home server automatically switch from a "free to
 | 
						|
chat" or "online" mode into "idle".
 | 
						|
 | 
						|
When a user is offline, the Home Server can still report when the user was last
 | 
						|
seen online, again perhaps in a somewhat coarse manner.
 | 
						|
 | 
						|
Device Type
 | 
						|
-----------
 | 
						|
 | 
						|
Client devices that may limit the user experience somewhat (such as "mobile"
 | 
						|
devices with limited ability to type on a real keyboard or read large amounts of
 | 
						|
text) should report this to the home server, as this is also useful information
 | 
						|
to report as "presence" if the user cannot be expected to provide a good typed
 | 
						|
response to messages.
 | 
						|
 | 
						|
 | 
						|
Presence List
 | 
						|
=============
 | 
						|
 | 
						|
Each user's home server stores a "presence list" for that user. This stores a
 | 
						|
list of other user IDs the user has chosen to add to it (remembering any ACL
 | 
						|
Pointer if appropriate).
 | 
						|
 | 
						|
To be added to a contact list, the user being added must grant permission. Once
 | 
						|
granted, both user's HS(es) store this information, as it allows the user who
 | 
						|
has added the contact some more abilities; see below. Since such subscriptions
 | 
						|
are likely to be bidirectional, HSes may wish to automatically accept requests
 | 
						|
when a reverse subscription already exists.
 | 
						|
 | 
						|
As a convenience, presence lists should support the ability to collect users
 | 
						|
into groups, which could allow things like inviting the entire group to a new
 | 
						|
("ad-hoc") chat room, or easy interaction with the profile information ACL
 | 
						|
implementation of the HS.
 | 
						|
 | 
						|
 | 
						|
Presence and Permissions
 | 
						|
========================
 | 
						|
 | 
						|
For a viewing user to be allowed to see the presence information of a target
 | 
						|
user, either
 | 
						|
 | 
						|
 * The target user has allowed the viewing user to add them to their presence
 | 
						|
   list, or
 | 
						|
 | 
						|
 * The two users share at least one room in common
 | 
						|
 | 
						|
In the latter case, this allows for clients to display some minimal sense of
 | 
						|
presence information in a user list for a room.
 | 
						|
 | 
						|
Home servers can also use the user's choice of presence state as a signal for
 | 
						|
how to handle new private one-to-one chat message requests. For example, it
 | 
						|
might decide:
 | 
						|
 | 
						|
  "free to chat": accept anything
 | 
						|
  "online": accept from anyone in my addres book list
 | 
						|
  "busy": accept from anyone in this "important people" group in my address
 | 
						|
    book list
 | 
						|
 | 
						|
 | 
						|
API Efficiency
 | 
						|
==============
 | 
						|
 | 
						|
A simple implementation of presence messaging has the ability to cause a large
 | 
						|
amount of Internet traffic relating to presence updates. In order to minimise
 | 
						|
the impact of such a feature, the following observations can be made:
 | 
						|
 | 
						|
 * There is no point in a Home Server polling status for peers in a user's
 | 
						|
   presence list if the user has no clients connected that care about it.
 | 
						|
 | 
						|
 * It is highly likely that most presence subscriptions will be symmetric - a
 | 
						|
   given user watching another is likely to in turn be watched by that user.
 | 
						|
 | 
						|
 * It is likely that most subscription pairings will be between users who share
 | 
						|
   at least one Room in common, and so their Home Servers are actively
 | 
						|
   exchanging message PDUs or transactions relating to that Room.
 | 
						|
 | 
						|
 * Presence update messages do not need realtime guarantees. It is acceptable to
 | 
						|
   delay delivery of updates for some small amount of time (10 seconds to a
 | 
						|
   minute).
 | 
						|
 | 
						|
The general model of presence information is that of a HS registering its
 | 
						|
interest in receiving presence status updates from other HSes, which then
 | 
						|
promise to send them when required. Rather than actively polling for the
 | 
						|
currentt state all the time, HSes can rely on their relative stability to only
 | 
						|
push updates when required.
 | 
						|
 | 
						|
A Home Server should not rely on the longterm validity of this presence
 | 
						|
information, however, as this would not cover such cases as a user's server
 | 
						|
crashing and thus failing to inform their peers that users it used to host are
 | 
						|
no longer available online. Therefore, each promise of future updates should
 | 
						|
carry with a timeout value (whether explicit in the message, or implicit as some
 | 
						|
defined default in the protocol), after which the receiving HS should consider
 | 
						|
the information potentially stale and request it again.
 | 
						|
 | 
						|
However, because of the likelyhood that two home servers are exchanging messages
 | 
						|
relating to chat traffic in a room common to both of them, the ongoing receipt
 | 
						|
of these messages can be taken by each server as an implicit notification that
 | 
						|
the sending server is still up and running, and therefore that no status changes
 | 
						|
have happened; because if they had the server would have sent them. A second,
 | 
						|
larger timeout should be applied to this implicit inference however, to protect
 | 
						|
against implementation bugs or other reasons that the presence state cache may
 | 
						|
become invalid; eventually the HS should re-enquire the current state of users
 | 
						|
and update them with its own.
 | 
						|
 | 
						|
The following workflows can therefore be used to handle presence updates:
 | 
						|
 | 
						|
 1 When a user first appears online their HS sends a message to each other HS
 | 
						|
   containing at least one user to be watched; each message carrying both a
 | 
						|
   notification of the sender's new online status, and a request to obtain and
 | 
						|
   watch the target users' presence information. This message implicitly
 | 
						|
   promises the sending HS will now push updates to the target HSes.
 | 
						|
 | 
						|
 2 The target HSes then respond a single message each, containing the current
 | 
						|
   status of the requested user(s). These messages too implicitly promise the
 | 
						|
   target HSes will themselves push updates to the sending HS.
 | 
						|
 | 
						|
   As these messages arrive at the sending user's HS they can be pushed to the
 | 
						|
   user's client(s), possibly batched again to ensure not too many small
 | 
						|
   messages which add extra protocol overheads.
 | 
						|
 | 
						|
At this point, all the user's clients now have the current presence status
 | 
						|
information for this moment in time, and have promised to send each other
 | 
						|
updates in future.
 | 
						|
 | 
						|
 3 The HS maintains two watchdog timers per peer HS it is exchanging presence
 | 
						|
   information with. The first timer should have a relatively small expiry
 | 
						|
   (perhaps 1 minute), and the second timer should have a much longer time
 | 
						|
   (perhaps 1 hour).
 | 
						|
 | 
						|
 4 Any time any kind of message is received from a peer HS, the short-term
 | 
						|
   presence timer associated with it is reset.
 | 
						|
 | 
						|
 5 Whenever either of these timers expires, an HS should push a status reminder
 | 
						|
   to the target HS whose timer has now expired, and request again from that
 | 
						|
   server the status of the subscribed users.
 | 
						|
 | 
						|
 6 On receipt of one of these presence status reminders, an HS can reset both
 | 
						|
   of its presence watchdog timers.
 | 
						|
 | 
						|
To avoid bursts of traffic, implementations should attempt to stagger the expiry
 | 
						|
of the longer-term watchdog timers for different peer HSes.
 | 
						|
 | 
						|
When individual users actively change their status (either by explicit requests
 | 
						|
from clients, or inferred changes due to idle timers or client timeouts), the HS
 | 
						|
should batch up any status changes for some reasonable amount of time (10
 | 
						|
seconds to a minute). This allows for reduced protocol overheads in the case of
 | 
						|
multiple messages needing to be sent to the same peer HS; as is the likely
 | 
						|
scenario in many cases, such as a given human user having multiple user
 | 
						|
accounts.
 | 
						|
 | 
						|
 | 
						|
API Requirements
 | 
						|
================
 | 
						|
 | 
						|
The data model presented here puts the following requirements on the APIs:
 | 
						|
 | 
						|
Client-Server
 | 
						|
-------------
 | 
						|
 | 
						|
Requests that a client can make to its Home Server
 | 
						|
 | 
						|
 * get/set current presence state
 | 
						|
   Basic enumeration + ability to set a custom piece of text
 | 
						|
 | 
						|
 * report per-device idle time
 | 
						|
   After some (configurable?) idle time the device should send a single message
 | 
						|
   to set the idle duration. The HS can then infer a "start of idle" instant and
 | 
						|
   use that to keep the device idleness up to date. At some later point the
 | 
						|
   device can cancel this idleness.
 | 
						|
 | 
						|
 * report per-device type
 | 
						|
   Inform the server that this device is a "mobile" device, or perhaps some
 | 
						|
   other to-be-defined category of reduced capability that could be presented to
 | 
						|
   other users.
 | 
						|
 | 
						|
 * start/stop presence polling for my presence list
 | 
						|
   It is likely that these messages could be implicitly inferred by other
 | 
						|
   messages, though having explicit control is always useful.
 | 
						|
 | 
						|
 * get my presence list
 | 
						|
   [implicit poll start?]
 | 
						|
   It is possible that the HS doesn't yet have current presence information when
 | 
						|
   the client requests this. There should be a "don't know" type too.
 | 
						|
 | 
						|
 * add/remove a user to my presence list
 | 
						|
 | 
						|
Server-Server
 | 
						|
-------------
 | 
						|
 | 
						|
Requests that Home Servers make to others
 | 
						|
 | 
						|
 * request permission to add a user to presence list
 | 
						|
 | 
						|
 * allow/deny a request to add to a presence list
 | 
						|
 | 
						|
 * perform a combined presence state push and subscription request
 | 
						|
   For each sending user ID, the message contains their new status.
 | 
						|
   For each receiving user ID, the message should contain an indication on
 | 
						|
   whether the sending server is also interested in receiving status from that
 | 
						|
   user; either as an immediate update response now, or as a promise to send
 | 
						|
   future updates.
 | 
						|
 | 
						|
Server to Client
 | 
						|
----------------
 | 
						|
 | 
						|
[[TODO(paul): There also needs to be some way for a user's HS to push status
 | 
						|
updates of the presence list to clients, but the general server-client event
 | 
						|
model currently lacks a space to do that.]]
 |