Internet-Draft
Date: 4. 4. 04
Expires: when 1.0 is ready
©1995 - 2011
C. von Loesch



Protocol for SYnchronous Conferencing

<draft-vonLoesch-psyc-00>
http://www.psyc.eu/psyc.html

Status of this Memo

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:

  1. text/x-enhanced
    	:= ISO-8859-1 (latin-1)
    	+ bold, reverse, italics, underline, blink
    	+ fgcolor (ink), bgcolor (paper)		# maybe
    
  2. text/html
    	:= text/html incl. style sheets!
    
  3. 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.