Updated documentation.

Added: Documentation for PHP server libraries.
Updated: Documentation for the Node.js server.
Esse commit está contido em:
Joshua Gross
2010-02-14 13:03:27 -06:00
commit 130ea4f87b
4 arquivos alterados com 236 adições e 7 exclusões
+65
Ver Arquivo
@@ -13,10 +13,18 @@
* Requirements: Database
*/
// == Default Server Library ==
//
// This is the default PHP-only server library. This library allows you
// to use Ajax IM on a shared server, without installing any extra software.
class Default_IM extends IM {
const FIXBUFFER = 1024; // Works around an output buffering issue in IE & Safari
const FIXEOL = '<br/>'; // Works around an end-of-line issue in Safari
// === {{{Default_IM::}}}**{{{__construct()}}}** ===
//
// Initializes the IM library and retrieves the user's session, if one
// currently exists.
function __construct() {
parent::__construct();
@@ -27,6 +35,14 @@ class Default_IM extends IM {
}
}
// === {{{Default_IM::}}}**{{{login($username, $password)}}}** ===
//
// Authenticate a user against the database. If the user is valid,
// log them in.
//
// ==== Parameters ====
// * {{{$username}}} is the user's login name.\\
// * {{{$password}}} is an already-md5'd copy of the user's password.
public function login($username, $password) {
if($user = User::authenticate($username, $password)) {
// user just logged in, update login time.
@@ -43,6 +59,9 @@ class Default_IM extends IM {
}
}
// === {{{Default_IM::}}}**{{{logout()}}}** ===
//
// Signs the user out.
public function logout() {
session_destroy();
$_SESSION = array();
@@ -50,6 +69,14 @@ class Default_IM extends IM {
return array('r' => 'logged out');
}
// === {{{Default_IM::}}}**{{{send($to, $message)}}}** ===
//
// Send a message to another user by adding the message to the
// database.
//
// ==== Parameters ====
// * {{{$to}}} is the username of the recipient.\\
// * {{{$message}}} is the content.
public function send($to, $message) {
if(!$this->username)
return array('r' => 'error', 'e' => 'no session found');
@@ -67,6 +94,10 @@ class Default_IM extends IM {
}
}
// === {{{Default_IM::}}}**{{{status($status, $message)}}}** ===
//
// Sets the status of the current user, including any associated
// status message.
public function status($status, $message) {
if(!$this->username)
return array('r' => 'error', 'e' => 'no session found');
@@ -89,6 +120,13 @@ class Default_IM extends IM {
}
}
// === {{{Default_IM::}}}**{{{register($username, $password)}}}** ===
//
// Create a new user based on the provided username and password.
//
// ==== Parameters ====
// * {{{$username}}} is the new user's login name.\\
// * {{{$password}}} is the user's plaintext password.
public function register($username, $password) {
if(preg_match('/^[A-Za-z0-9_.]{3,16}$/', $username)) {
if(strlen($password) > 3) {
@@ -129,6 +167,14 @@ class Default_IM extends IM {
}
}
// === {{{Default_IM::}}}**{{{poll($method)}}}** ===
//
// Query the database for any new messages, and respond (or wait)
// using the specified method (short, long, or comet).
//
// ==== Parameters ====
// * {{{$method}}} is the type of response method to use as a reply.
// See {{{im.js}}} for a description of each method.
public function poll($method) {
if(!$this->username)
return array('r' => 'error', 'e' => 'no session found');
@@ -165,6 +211,9 @@ class Default_IM extends IM {
}
}
// === //private// {{{Default_IM::}}}**{{{_longPoll()}}}** ===
//
// Use the long polling technique to check for and deliver new messages.
private function _longPoll() {
set_time_limit(30);
@@ -189,6 +238,9 @@ class Default_IM extends IM {
return array();
}
// === //private// {{{Default_IM::}}}**{{{_shortPoll()}}}** ===
//
// Use the short polling technique to check for and deliver new messages.
private function _shortPoll() {
$messages = Message::getMany('to', $this->user_id);
@@ -199,6 +251,9 @@ class Default_IM extends IM {
}
}
// === //private// {{{Default_IM::}}}**{{{_comet()}}}** ===
//
// Use the comet/streaming technique to check for and deliver new messages.
private function _comet() {
set_time_limit(0);
@@ -224,6 +279,12 @@ class Default_IM extends IM {
}
}
// === //private// {{{Default_IM::}}}**{{{_pollParseMessages()}}}** ===
//
// Parse each message object and return it as an array deliverable to the client.
//
// ==== Parameters ====
// * {{{$messages}}} is the array of message objects.
private function _pollParseMessages($messages) {
$msg_arr = array();
foreach($messages as $msg) {
@@ -232,6 +293,10 @@ class Default_IM extends IM {
return $msg_arr;
}
// === //private// {{{Default_IM::}}}**{{{_sanitize()}}}** ===
//
// Sanitize messages by preventing any HTML tags from being created
// (replaces &lt; and &gt; entities).
private function _sanitize($str) {
return str_replace('>', '&gt;', str_replace('<', '&lt;', str_replace('&', '&amp;', $str)));
}
+38
Ver Arquivo
@@ -13,7 +13,15 @@
* Requirements: Database, Node.js
*/
// == Node.js Server Library ==
//
// This is the [[http://nodejs.org|Node.js]] server library for Ajax IM. It
// handles registration and passing login to the Node.js server.
class NodeJS_IM extends IM {
// === {{{NodeJS_IM::}}}**{{{__construct()}}}** ===
//
// Initializes the IM library and retrieves the user's session, if one
// currently exists.
function __construct() {
parent::__construct();
@@ -35,10 +43,21 @@ class NodeJS_IM extends IM {
}
}
// === {{{NodeJS_IM::}}}**{{{__destruct()}}}** ===
//
// Closes the connection to the Node.js server.
function __destruct() {
$this->memcache->close();
}
// === {{{NodeJS_IM::}}}**{{{login($username, $password)}}}** ===
//
// Authenticate a user against the database. If the user is valid,
// pass the user's information to the Node.js server.
//
// ==== Parameters ====
// * {{{$username}}} is the user's login name.\\
// * {{{$password}}} is an already-md5'd copy of the user's password.
public function login($username, $password) {
if($user = User::authenticate($username, $password)) {
// user just logged in, update login time.
@@ -65,12 +84,22 @@ class NodeJS_IM extends IM {
}
}
// === {{{NodeJS_IM::}}}**{{{logout()}}}** ===
//
// Signs the user out of the Node.js server.
public function logout() {
$this->memcache->delete($this->username);
return array('r' => 'logged out');
}
// === {{{NodeJS_IM::}}}**{{{register($username, $password)}}}** ===
//
// Create a new user based on the provided username and password.
//
// ==== Parameters ====
// * {{{$username}}} is the new user's login name.\\
// * {{{$password}}} is the user's plaintext password.
public function register($username, $password) {
if(preg_match('/^[A-Za-z0-9_.]{3,16}$/', $username)) {
if(strlen($password) > 3) {
@@ -111,6 +140,15 @@ class NodeJS_IM extends IM {
}
}
// === {{{NodeJS_IM::}}}**{{{add_friend($friend, $group)}}}** ===
//
// Add a new friend to the current user's friend list, in the specified
// group name. Adds the friend to both the database and the current
// Node.js server session.
//
// ==== Parameters ====
// * {{{$friend}}} is the username of the friend.\\
// * {{{$group}}} is the name of group in which to place the friend.
public function add_friend($friend, $group) {
if(!$this->username)
return array('r' => 'error', 'e' => 'no session found');
+24
Ver Arquivo
@@ -14,7 +14,17 @@
* Requirements: Node.js
*/
// == Node.js Guest Server Library ==
//
// This is the [[http://nodejs.org|Node.js]] Guest server library for Ajax IM. It
// creates a random "Guest" username upon login and passes that information to
// the Node.js server. Additionally, it makes every user a friend of every other
// user.
class NodeJS_Guests_IM extends IM {
// === {{{NodeJS_Guests_IM::}}}**{{{__construct()}}}** ===
//
// Initializes the IM library and retrieves the user's session, if one
// currently exists.
function __construct() {
parent::__construct();
@@ -35,10 +45,21 @@ class NodeJS_Guests_IM extends IM {
}
}
// === {{{NodeJS_Guests_IM::}}}**{{{__destruct()}}}** ===
//
// Closes the connection to the Node.js server.
function __destruct() {
$this->memcache->close();
}
// === {{{NodeJS_IM::}}}**{{{login($username, $password)}}}** ===
//
// Create a new Guest username based in the microtime, then
// pass the user's information to the Node.js server.
//
// ==== Parameters ====
// * {{{$username}}} is unused (kept for compatability with caller).\\
// * {{{$password}}} is unused (kept for compatability with caller).
public function login($username='', $password='') {
$username = 'Guest' . (microtime(true) * 100);
$session_id = md5(microtime(true) . $username);
@@ -83,6 +104,9 @@ class NodeJS_Guests_IM extends IM {
);
}
// === {{{NodeJS_IM::}}}**{{{logout()}}}** ===
//
// Signs the user out of the Node.js server.
public function logout() {
$this->memcache->delete($this->username);
+109 -7
Ver Arquivo
@@ -166,13 +166,12 @@ var AjaxIM = function(config) {
// exist, {{{false}}} is returned. If {{{'object'}}} is requested and
// there is no active session for that user, {{{false}}} is also returned.
//
// {{{request}}} is a request object, as is provided by the {{{http}}} module
// {{{provide}}} is one of:
// * {{{username}}} which merely checks for the existence of session data and
// ==== Parameters ====
// * {{{request}}} is a request object, as is provided by the {{{http}}} module
// * {{{provide}}} is one of:
// ** {{{username}}} which merely checks for the existence of session data and
// returns the username for that session.
// * {{{object}}} checks for the existence of the session //and// the existence
// of an active session (the user is currently logged in), and returns the user
// object, if found.
// ** {{{object}}} checks for the existence of the session //and// the existence of an active session (the user is currently logged in), and returns the user object, if found.
this._session = function(request, provide) {
if(this.config.cookie.name in request.cookies) {
try {
@@ -214,7 +213,9 @@ var AjaxIM = function(config) {
//
// If debugging is enabled, this function prints debug data, with the
// current formatted time, to the console.
// {{{str}}} is the debug string.
//
// ==== Parameters ====
// * {{{str}}} is the debug string.
this._d = function(str) {
if(this.debug) {
var addZero = function(str) { return str < 10 ? '0' + str : str; };
@@ -228,6 +229,19 @@ var AjaxIM = function(config) {
};
// === //private//\\ {{{ AjaxIM._initUser(username, data) }}} ===
//
// Initializes a user session and adds the user to the users list. Additionally,
// it stores a callback function which will push data directly to this user. A
// "session" object is also stored, allowing a user to reconnect at a later time
// (provided that their session hasn't yet expired).
//
// ==== Parameters ====
// * {{{username}}} is the user's account name\\
// * {{{data}}} is an array of user data:\\
// ** {{{user_id}}} is a unique id for this particular user.
// ** {{{session_id}}} is the user's unique session id (used to (re)connect to the server).
// ** {{{friends}}} is the friends list.
// ** {{{guest}}} (optional) defines whether or not this is a "guest" (temporary) user.
this._initUser = function(username, data) {
if(data['user_id']) {
self._d('User [' + username + '] has connected. Adding to user hash and notifying friends.');
@@ -284,6 +298,10 @@ var AjaxIM = function(config) {
};
// === //private//\\ {{{ AjaxIM._killUser() }}} ===
//
// Remove a user from the server. If they are a guest user, also remove
// their session data; otherwise, retain session data so that the user's
// session can be resumed later.
this._killUser = function(username) {
if(!username || !(username in self.users))
return false;
@@ -316,6 +334,10 @@ var AjaxIM = function(config) {
};
// === {{{ AjaxIM.poll() }}} ===
//
// Store the user's connection in the callback list and update both the
// user and session "last_active" variable (denoting when the user last
// contacted the server).
this.poll = function() {
if(this.debug && ('sid' in this.request.uri.params && this.request.uri.params['sid'].length))
this.request.cookies[self.config.cookie.name] = {sid: this.request.uri.params.sid};
@@ -337,6 +359,9 @@ var AjaxIM = function(config) {
};
// === {{{ AjaxIM.resume() }}} ===
//
// Attempt to resume a session based on a session id stored in a
// cookie.
this.resume = function() {
if(!(user = self._session(this.request, 'username'))) {
this.response.reply(200, {'r': 'error', 'e': 'no session found'});
@@ -352,6 +377,10 @@ var AjaxIM = function(config) {
};
// === {{{ AjaxIM.send() }}} ===
//
// Send a message to the user specified in the query and return a
// result declaring whether or not the message was sent. Messages
// are only sent if the user has an active session.
this.send = function() {
var sent = false;
@@ -385,6 +414,11 @@ var AjaxIM = function(config) {
};
// === {{{ AjaxIM.status() }}} ===
//
// Update a user's status based on the query parameters; this includes
// both their status code and any custom status message associated with
// that code. If the status update is successful, send an update to the
// user's friends.
this.status = function() {
var status_updated = false;
@@ -422,16 +456,31 @@ var AjaxIM = function(config) {
};
// === {{{ AjaxIM.online() }}} ===
//
// Return a count of the number of online users.
this.online = function() {
this.response.reply(200, {count: self.onlineCount});
};
// === {{{ AjaxIM.apiLogin(username, data) }}} ===
//
// A Memcache API function. Initializes a new user based on the
// sent username and decoded JSON user data.
//
// ==== Parameters ====
// * {{{username}}} is the unique username to initialize.
// * {{{data}}} is the user data outlined in the _initUser function.
this.apiLogin = function(username, data) {
this._initUser.call(self, username, data);
};
// === {{{ AjaxIM.apiGetUser(username) }}} ===
//
// A Memcache API function. Returns user data based on a
// specified username.
//
// ==== Parameters ====
// * {{{username}}} is the name of the user to retrieve.
this.apiGetUser = function(username) {
var user = this.users[username];
return {
@@ -443,6 +492,12 @@ var AjaxIM = function(config) {
};
// === {{{ AjaxIM.apiGetSession(session_id) }}} ===
//
// A Memcache API function. Returns user data based on a
// specified session id. Returns the same data as apiGetUser.
//
// ==== Parameters ====
// * {{{session_id}}} is the session id of the user to retrieve.
this.apiGetSession = function(session_id) {
if(session_id in this.sessions)
return this.apiGetUser(this.sessions[session_id].username);
@@ -451,6 +506,9 @@ var AjaxIM = function(config) {
};
// === {{{ AjaxIM.apiGetUserList() }}} ===
//
// A Memcache API function. Returns user data for all online users.
// Same data returned as apiGetUser, but in an array of all users.
this.apiGetUserList = function() {
var users = [];
for(var username in this.users) {
@@ -468,11 +526,26 @@ var AjaxIM = function(config) {
};
// === {{{ AjaxIM.apiOnlineCount() }}} ===
//
// A Memcache API function. Returns a count of all online users.
this.apiOnlineCount = function() {
return {count: this.onlineCount};
};
// === {{{ AjaxIM.apiAddFriend(type, id, value) }}} ===
//
// A Memcache API function. Adds a user to the friends list
// of another user. Note, however, that this only adds the friend
// to the user's active session; it does not add the friend permanently
// to any database that might be in use.
//
// ==== Parameters ====
// * {{{type}}} is the type of identifier used to identify the user. One of
// "session" or "username".\\
// * {{{id}}} is the actual identifier; a username or session id.\\
// * {{{value}}} is an array of data about the new friend:
// ** {{{u}}} is the username of the friend.
// ** {{{g}}} is the group into which the friend will be placed.
this.apiAddFriend = function(type, id, value) {
if(type == 'session') {
if(id in this.sessions)
@@ -499,6 +572,14 @@ var AjaxIM = function(config) {
};
// === {{{ AjaxIM.apiRemoveFriend(type, id, value) }}} ===
//
// A Memcache API function. Does the exact opposite of {{{apiAddFriend}}}.
//
// ==== Parameters ====
// * {{{type}}} is the type of identifier used to identify the user. One of
// "session" or "username".\\
// * {{{id}}} is the actual identifier; a username or session id.\\
// * {{{value}}} is the username of the friend to remove.
this.apiRemoveFriend = function(type, id, value) {
if(type == 'session') {
if(id in this.sessions)
@@ -523,6 +604,14 @@ var AjaxIM = function(config) {
};
// === {{{ AjaxIM.apiBroadcastMessage(type, id, value) }}} ===
//
// A Memcache API function. Broadcasts a message of type "message" ("m")
// to all signed-in users.
//
// ==== Parameters ====
// * {{{type}}} should be "from".\\
// * {{{id}}} is the name of the sender; can be anything.\\
// * {{{value}}} is message.
this.apiBroadcastMessage = function(type, id, value) {
if(type != 'from' || !id.length)
return false;
@@ -535,7 +624,20 @@ var AjaxIM = function(config) {
};
// === {{{ AjaxIM.apiBroadcastRaw(type, id, value) }}} ===
//
// A Memcache API function. Broadcasts a message of the specified
// type to all signed-in users.
//
// ==== Parameters ====
// * {{{type}}} should be "from".\\
// * {{{id}}} is the name of the sender; can be anything.\\
// * {{{value}}} is message object:
// ** {{{t}}} is the type of message.
// ** {{{s}}} is the sender.
// ** {{{r}}} is the recipient (usually irrelevant in broadcasted messages).
// ** {{{m}}} is the content of the message.
this.apiBroadcastRaw = function(type, id, value) {
// Why "from?" This needs to be reconsidered.
if(type != 'from' || !id.length || typeof value != 'object')
return false;