This document describes portions of version 0.99 of the PSYC Protocol for
SYnchronous Conferencing. You may consider it an Internet-Draft and as such
subject to all provisions of Section 10 of RFC2026 except that the right to
produce derivative works is not granted.
In all matters of intellectual property rights and procedures, the
intention is to benefit the Internet community and the public at
large, while respecting the design decision to keep the original author
of the protocol in charge. We don't like the bloat effects other efforts
are experiencing.
Only if you have developed an application in accordance to this specification
you may call it PSYC-compliant to the version mentioned above.
Abstract
This document describes a generic extensible object oriented message
format to be transported by a message protocol such as MMP.
It has been designed to be easily implementable, text-based but -- at the same time --
low in overhead.
Syntax
{message} :=
[ {modifier} ]*
# optional variable modifiers
[ {method}
# if the message consists only of a change in state
# (variable modifications) method and body may be missing
[ "\n" {body} ]
# depending on the method body may or may not be present
]
{psyc variable} :=
"_nick" # the preferred handle for message display
| "_nick_alternate" # an alternative, in case of nickname clash
| "_nick_alias" # short forms of the nicknames for the user
# to type, for instance "tbl tim t" for "TimBL"
# so the user can type "/m tim hi tim!" unless
# he knows some other tim too - in that case
# the user interface can warn of a clash and
# ask for further action to take
| "_nick_current" # temporary change of conversational nickname
# valid for the current context only
# (that is "you" or a group you're in)
# this is likely to be used for "acting", a
# creative chatting technique typically aimed
# at entertainment, but not necessarily.
| "_action" # a description of an action of the sender
# in plaintext using the currently selected
# character set (this is usually generated
# by the /me command). actions have a
# relevant impact on the chat atmosphere.
| "_identification" # UNI, when talking to a UNL
| "_location" # current UNL, when talking to a UNI
| "_interface" # reserved for future interface descriptions
| "_implementation" # 4-part code describing implementation
# details: architecture/os/software/version.
# if there is an internet standard for such
# codes you should probably adhere to that ;-)
# version may be left out for security reasons.
| "_name" # real name of a person - if you don't want to
# publish your real name simply don't send this
# variable, but please don't send false
# information here
| "_description" # a text description of the object - use this
# instead of _name for fun names.
| "_type_content" # type of body content
| "_web_homepage" # a URL pointing to a web page related to the
# object - if you're a friend of a person this
# person might be sending you his "homepage for
# friends" address instead of the public
# homepage.
| ... # more to follow
Variables can be set or modified within every PSYC message according to the
definition of Variable Modifiers.
Rationale
PSYC avoids the traditional object-oriented message structure
constituted by object, method and arguments and replaces the
arguments with variables which act much like environment
variables, plus the content body. The traditional concept of
function arguments suffers from subjecting the information to an unnecessary
constraint: order. PSYC can always extend
semantics of methods by adding variables and will always easily
be backwards compatible.
The following sections introduce the top level families
of PSYC methods and their most relevant children.
Remember that all messages MUST be ignored or, at the
user's option, be treated with a clearly reduced priority
if the sender is an object you have never had contact with
before and therefore constitutes an unsolicited communication.
Conversational Messages
All methods of the _message family are used to deliver human generated
text messages to humans. The default content type for "_message" could
be text/x-enhanced. Messages as any kind
Messages currently in use are
"_message_private" # this is equivalent to "_message"
# without a _context marker
"_message_public" # this is a temporary solution to make it easy
# for interfaces to distinguish public from
# private message and the appropriate looks,
# but the correct way to detect this is
# 1. by checking for _context, which
# defines a real psyc group
# 2. by distinguishing the _source of the
# message as being a room instead of a
# person.
"_message_announcement" # a broadcast message from your server
# administrator - should be ignored if it is
# not coming from your UNIs home server
"_message_behaviour" # these messages are currently sent by the
# psyced implementation as warnings or
# punishment information for misbehaving users.
Requests
The _request family contains requests for the recipient to
perform some action. They usually do not contain content, but if
they do, the content is by default of type "text/x-enhanced".
One particular request must be supported by any object: The
"_request_talk" method is the default method a web-integrated PSYC
client calls when its user clicks on a PSYC UNL. The communication
can either be granted by an "_info_talk" message, or denied with an
"_error_rejected_talk". See below for details on replies.
Additional other action may be taken as appropriate for the object
(for instance to make the web-user enter a group).
They way for a UNL to register with its UNI is to send a
"_request_link". The UNI will probably query for a password and
then send a "_status_linked", which should probably be a _notice rather
than a _status, since it describes a change in status and may also
happen asynchronously from your _request.
A "_status_unlinked" is the answer to a "_request_unlink", when
your client application is closing. Again: should be a notice.
A "_request_execute" is PSYC's functionality superhighway, since
a user interface is supposed to deliver any user command that it doesn't
have a use for, to the current communication counterpart. For instance if
the user enters "/topic", you are not supposed to handle that command
yourself. You should rather send it as a _request_execute (with the
command in the body) to the counterpart which in that case probably is
a chatroom, which happens to implement such a command. When you do not
have a current counterpart, for instance in your "console/status" window,
your command should be delivered to your UNI. This is how a client software
can appear to have an immense amount of functions, simply because your home
server hosting the UNI does. You may choose to provide multiple command
characters for built-in, UNI and chat counterpart commands, not just "/" -
but beware that this breaks the good old "Don't Mode Me" software design rule.
Other methods in use are:
"_request_authentication_ack" # to ask a UNI for authentication
# confirmation about a UNL
Requesting the content of a particular variable is not a _request,
it is a _query which is handled by the '?' glyph.
Replies
The following families have in common being replies, but since they
are so important I have not put them into a huge _reply family.
They also have in common being encoded with the content type of
text/x-psyc.
Messages of the _failure family inform the recipient
of the sender's inability to fulfill a request.
_error indicates a mistake in the way the request was made.
_warning informs you of potential trouble while
_info delivers other kind of textual information
which isn't human-generated. For acknowledgments that
contain no further information but to tell that a
particular request was appropriately handled,
_echo is the appropriate family. It should always
be safe to suppress them from being displayed. Instead, a client
could warn the user when an expected _echo fails to arrive (due
to network congestion).
_list is used for multiline listing outputs.
_status for the current status of things whose modification
you would otherwise receive in an equivalent _notice.
_notices are encoded in the same way as _status
messages, but they are the only messages of this kind which are no replies.
That's why they are described a little further below.
Specific conditions trigger specific methods, such as
"_error_unsupported_method" in the case when a recipient doesn't
understand a particular method. These are error methods currently
in use, but remember that your implementation MUST be capable of
accepting new methods within the known families. In fact some very
unusual methods the psyced implementation may be sending are left out
here, "_failure_object_creation" just to name an example.
"_failure_filter" # message not delivered because
# the user has set up a filter
"_failure_unsupported" # something as yet unimplemented
# or otherwise unsupported
"_error_illegal_name" # illegal chars in a password
"_error_illegal_password" # or user name or suchlike
"_error_invalid_password" # wrong password
"_info_commands" # a list of available commands
"_info_server_version"
"_info_set" # a UNI configuration setting
"_warning_usage" # usage syntax of several commands
"_echo_place_enter" # mere acknowledgments that your
"_echo_place_leave" # request has been executed
"_echo_set_description"
"_list_friends" # friends online
"_list_places" # a list of chat rooms
"_list_acquaintance_display" # list of ignored or highlighted
# people
"_list_acquaintance_notification" # list of all friends, actually
"_status_place" # various information about the
# current status of a chat room
"_status_friend_absent" # the status of a "buddy" of yours
"_status_friend_present"
"_status_person_absent" # the status of a person you are
"_status_person_present" # communicating with
Notices
As has been said before, the difference between _status and _notice methods is
that notices tell you about the change of status, and therefore may be
sent to you asynchronously from any request you may have sent.
These are the notices in use:
"_notice_friend_absent" # presence information of a friend
"_notice_friend_present" # of yours.. a "buddy" notification
User Clients
User clients are either programs directly interacting with the user,
or gatewaying his/her actions from a non-PSYC user interface (For instance
a Java applet or an IRC client).
User clients are required to support all messaging methods described
so far, and invited to provide as many PSYC variables they care to,
for instance _name containing the real name of the user.
Additionally, they are given the possibility of remote storage
of configuration variables, see "Remote Persistent Storage" for
details.
User Objects
User identifications (User-UNIs) point to user objects
which return the current location (UNL) of the user client,
unless they have some reason not to do so. The simplest way
to do so is for a sender to send a "?_location" query, but
it may as well send a complete _message, since
user objects are required to be capable of accepting
_message methods and synchronously or asynchronously forwarding
these messages to the user.
Methods supported by user objects: (Objects that start with ~)
"_request_talk"
"_request_link"
The _request_link method links a user client to a user object, the
user object might request all sorts of authentication before
acknowledging this client to be the current location of its user.
The simplest form for it is to send a "?_password" request for
the user's password.
Remote Persistent Storage
For persistent storage the variable family "_persistent" is
introduced. Server objects willing to provide this feature, typically
user objects interacting with user clients, apply variable modifiers
persistently to all variables in the _persistent family, whatever the
actual name is. However as multiple client implementations evolve it is
practical to use consistent names for those variables.
Right now this feature isn't implemented anywhere yet.
Group Managers
Managers of groups may or may not be using the actual PSYC conference
control protocol but they will provide the following methods:
"_request_talk"
"_request_enter"
"_request_leave"
They may want to accept messages of the _message family
for them to redistribute. They may also want to provide the
following variables:
"_members"
"_topic"
Servers
Server root objects could be providing statistics about the server
or lists of public rooms available etc. Right now psyced
replies to a "_query_users_amount" with a "_info_users_amount"
message containing the current amount of people logged into the
server.
PSYC State
The state of variables between communicating PSYC entities can be
maintained using the MMP _state module using
the appropriate Variable Modifier syntax.
The difference to MMP state however is that PSYC keeps an end-to-end
state between each source and logical target as defined
in the MMP. MMP already needs to keep counter for both incoming and
outgoing end-to-end communication between PSYC objects.
Enabling the _state module requires you to also keep a complete set
of incoming and outgoing persistent variables for each source and
logical target tuple. This may sound like work, but it brings great
advantages in the amount of traffic passing the network, when for example
you can assign the speak _action once, and it will most likely
see no further modification.
MMP Negotiation
The Negotiation of MMP modules, protocols etc. takes place in
PSYC packets from either a NULL _source or to a NULL _target
and _context. Such packets are to be handled by a special
MMP manager and need not be forwarded to any PSYC objects.
Details are in the MMP specification.
Probably they belong into their own document, even though
they depend on PSYC syntax but operate on MMP.
Universal Methods
Methods that every PSYC entity SHOULD support:
"_request_talk" # The method that gets triggered when a
# psyc-UNL is mouse-clicked. Should be
# equivalent to _request_enter for groups.
Methods that every PSYC root object SHOULD support:
"_request_echo" # PSYC's equivalent of ping.
"_request_trace" # PSYC's equivalent of traceroute.
Message Content Types
Suggestions for new MIME-style content-types for use with
typed text-based communication:
- text/x-enhanced
:= ISO-8859-1 (latin-1)
+ bold, reverse, italics, underline, blink
+ fgcolor (ink), bgcolor (paper) # maybe
- text/html
:= text/html incl. style sheets!
- text/x-psyc
:= ISO-8859-1 (latin-1)
+ "[" {variable} "]"
Example:
:_method i
_message_error_unsupported_method
No such method '[_method]' defined here.
This syntax allows for errors, warnings and other automatically generated
messages to be human readable as well as automatically parsable.
All of these content types use LF for line endings like HTTP, not
CRLF like MIME does. In fact the protocol as such uses LF for its
line endings, even if encapsuled into MIME. The content type for
complete PSYC/MMP messages themselves is message/x-psyc (uncaring of
the content-type of the data contained within). It needs to be
encapsulated in an 8-bit transparent way, as it may contain
binary data.
Discussion
The naming of the methods is tricky - it is still not sorted out
properly although I have recently spent an entire day just rearranging the families on paper. Months have passed
since and I suddenly don't understand why I renamed the
beautiful _conversation too generically _message, to name one
particular issue.
Come forward with any suggestions.