Home
Demo
Download
Documentation
Community
Credit

 

ICEspresso Chat Framework

 

Developer Guide

Demo Codes

Support Resources

Latest Blog Posts

powered by Push4Free.com

Docs > Howto > Friend Events

How to set-up and handle friend-related events

ICEspresso Framework come with a powerful feature that supports real-time web presence notification. We will in this how-to section walk developers through the details. Our goal is to help developers add this functionality to their arsenals for building an application capable of web presence alert in real-time fashion.

The demo as well as the guide require fundamental knowledge of how ICEspresso works. You may refer to the Getting Started tutorial if such knowledge is lacking.

Table of Contents

Running The Example

1.1. Running the online example.

To demonstrate the ideas behind friend event, we provided Friends' Status online demo for an interactive experience. You are encouraged to try this sample out to visually observe the event logic.

 

1.2. Entering the unique key.

After accessing the above link, you should see the page shown below


(Figure 1. Choose a key to register with ICEspresso Service)

The "key" mentioned should be thought as a token to ICEspresso Service. Unlike nickname which can be changed from time to time depending on application's needs, the key specified persists through the entire application's session scope.

 

1.3. Understanding the friend list.

After clicking on the 'Create Friend List' button, you will be directed to a chat-room like page as shown below:


(Figure 2. Screen shot of the page)

In this page, you should immediately spot the three links and a short description of what they are for. Likewise, there is a floating log pane at the bottom of the page that lists out the course of action performed. If you should notice, there is a line stating 'Set my friends to icex_0, icex_1, icex_2' in the log pane. To the right, you will also discover a section labeled as 'Friend', below which the three virtual friends icex_0, icex_1, and icex_2 are listed.

The idea of this demo is to within a single application access ICEspresso Service using different identities. Based on the key you've chosen in the starting page, the application arbitrarily select three other keys by appending a number to the initial key.

By clicking on any of the links, you will initiate another session using different key, meaning that you are signing into the ICEspresso Service using a different identity.

We will refer to this page as observing page.

 

1.4. Impersonating the virtual friend.

In this step, you should click on the link that reads 'Using icex_0 as unique key'. A new window will appear and load in an instant. A sample screen shot is provided below:


(Figure 3. virtual friend 'icex_0' has just signed in)

The newly opened window lives on a fresh session using 'icex_0' as key. You need to check the initial window to see what has happened.


(Figure 4. virtual friend 'icex_0' has just signed in)

The online notification arrived immediately at the time icex_0 signed in thanks to the implemented push technology. You should also notice that the friend section to right is reporting the same status.

1.5. Observing the friend status.

Back to the newly opened window owned by 'icex_0' session, you should discover that there are four buttons labeling 'Go Online', 'Go Offline', 'Join Room', and 'Quit Room'. These four buttons are presented to let you easily simulate the friend events within ICEspresso system. By clicking these buttons and checking back the observing page. You should quickly discover the promptness of this event notify and update.


(Figure 5. The event buttons)

This type of event notification is driven by push technology; the observer receives the status update without having to ask for it periodically.

 

1.6. Requesting friend status.

Back to the observing page, there is a button at the bottom labeled as 'List Friends'. By clicking this button, you will be requesting friend's status actively. There are times that it becomes necessary to ask information from server instead of waiting for events to occur. ICEspresso Service does provide this feature to suit application's needs.


(Figure 6. Result of active request of friend status)

This type of operation is known as pulling. Though less preferred to pushing in terms of resource consumption, it may prove to be useful in some occasions.

 

1.7. Deploying the example locally.

If you would like to play with the source code, the package may be downloaded from this link. The package contains the source code (written in PHP) as well as the ICEspresso Framework files that are required to run the sample.

You will need a PHP-enabled web server to host this application. PHP skill is not really required as the source code only utilizes the simplest PHP functions to print out variables that need to be passed across pages.

 

Take A Look Inside

2.1. How does the system work?

The system works in such a way that relies on key registration with ICEspresso Service upon connection. That is, each connected link specifies a key that is unique to the hosting system. The ICEspresso Service would associate the key with the link. If someone has been monitoring the presence of such key, a notification message is sent to the monitoring party.

In the demo given above, icex has expressed interest in knowing the presence and whereabouts of icex_0, icex_1, and icex_2. The ICEspresso Service remembers this by maintaining a friend list that belongs to icex. When icex_0 signs in, the ICEspresso Service immediately notifies icex of icex_0's presence.

2.2. Where can I find the API reference?

The complete API reference documentation can be found on apireference.php.

2.3. How do I specify the key to register with ICEspresso Service?

The key is specified in connect() call.

<script language="javascript">
var chatInst = null;

icespresso.onSystemEvent = function(chat, eventId, arg) {
    switch (eventId) {
        case chat.SYS_INITIALIZED: {
            var prop = {
                // define connection properties here
            };
            var key = "foo";
            chatInst.connect(prop, key);
            break;
        }
    }
}

chatInst = icespresso.initialize();
</script>

The key can only be assigned at connect() call and is not changeable once assigned. This is by design intentional to ensure performance and integrity of ICEspresso Service.

If you have already skimmed through the API reference, the second parameter in the connect() method is named uniqueKey. This is explained in the next item.

 

2.4. What do you mean by "the key needs to be unique"?

Specifying the 'key' in connect() call in ICEspresso Service's context is called 'user-binding'. The binding allows ICEspresso Service to uniquely identify each connected session. Much more like user system where each user must be uniquely identifiable so is ICEspresso Service in this regard.

The user binding process also has the added benefits of session persistence. Under the hood, when you connect to ICEspresso Service within a web page, a navigation to another page inescapably results in socket disconnection. But if you re-establish the connection with the same key in next subsequent page, ICEspresso Service will recognize that this is a connection that results from page navigation and will remember your state, i.e., nickname and friend list. This implicitly implies that the key must be unique in order to preserve the data integrity (Two users with different session state but sharing the same key sooner or later messes up the state).

2.5. How I do set my friend list?

The friend list is set using icespresso's class method setFriends().

<script language="javascript">
var chatInst = null;

icespresso.onSystemEvent = function(chat, eventId, arg) {
    switch (eventId) {
        case chat.SYS_INITIALIZED: {
            var prop = {
                // define connection properties here
            };
            var key = "foo";
            chatInst.connect(prop, key);
            break;
        }
        
        // SYS_HANDSHAKED should be considered as the entry point
        // to perform system-level operation
        case chat.SYS_HANDSHAKED: {
            // friend list needs to be an index-based array
            var arrFriends = new Array();
            // using JavaScript array's push method to add elements
            arrFriends.push("bar");
            arrFriends.push("baz");
            // Pass the array to setFriends() method
            chatInst.setFriends(arrFriends);
            break;
        }
    }
}

chatInst = icespresso.initialize();
</script>

setFriends() cannot be called unless SYS_HANDSHAKED event has been signaled. The API reference documentation contains more information on this restriction.

2.6. Why must I provide my own key in connect() call when I am just monitoring others?

By design, the ICEspresso Service maintains three in-memory maps for retrieving and storing friend lists of each connected clients. If a client wishes to monitor others, a key must be provided in order for ICEspresso Service to keep the data integrity.

 

2.7. Does ICEspresso Service save the friend list I set to a persistent storage

No, ICEspresso does not keep a local copy of the friend list. The friend list is kept only when the session is active. When connected client explicitly calls disconnect() or idles out, the friend list is removed from the ICEspesso Service.

 

2.8. How do I set-up the event handler for monitoring friends?

All friend-related events are sent to onFriendEvent() callback handler. As with other callback handlers, we will add it to the running script and define the code behavior inside the handler.

<script language="javascript">
var chatInst = null;

icespresso.onFriendEvent = function(chat, eventId, arg) {
    switch (eventId) {
        
        case chat.FRIEND_ONLINE: {
            // called when friend comes online
            // define code behavior here
        }
        
        case chat.FRIEND_OFFLINE: {
            // called when friend goes online
            // define code behavior here
        }
        
        case chat.FRIEND_JOINROOM: {
            // called when friend joins a room
            // define code behavior here
        }
        
        case chat.FRIEND_QUITROOM: {
            // called when friend leaves a room
            // define code behavior here
        }
        
        case chat.FRIEND_LOCATION: {
            // called when we query friends' status
            // define code behavior here
        }
    }
}

chatInst = icespresso.initialize();
</script>

This is a basic friend event handler skeleton. The variable arg contains data that is different from event to event. Please consult the API reference for complete details.

 

2.9. Show me an example on how to update UI for visual alert when notification arrives.

Bar
<div id="bar_status">Offline</div>
Baz
<div id="baz_status">Offline</div>
<script language="javascript"> var chatInst = null; icespresso.onSystemEvent = function(chat, eventId, arg) { switch (eventId) { case chat.SYS_HANDSHAKED: { // Friend list is an index-based array // Key 'bar' and 'baz' are added to foo's friend list. arrFriends.push("bar"); arrFriends.push("baz"); chatInst.setFriends(arrFriends); // Important step, query friend's status first // Result will be sent to onFriendEvent with eventId set to FRIEND_LOCATION // Setting the parameter to 'true' indicates that we want // ICEspresso Service to return a full report of our friends // whether they are online or offline chatInst.getFriends(true); break; } } } icespresso.onFriendEvent = function(chat, eventId, arg) { switch (eventId) { case chat.FRIEND_LOCATION: { // This event is triggered because we explicitly called // getFriends() var friends = arg.friends; for (var key in friends) { if (!friends.hasOwnProperty(key)) continue; var o = document.getElementById(key + "_status"); // If we cannot find a matching HTML element for this friend, // then do next loop // This should not happen in this sample code but is provided // to keep up with good programming practice if (o == null) continue; var f = friends[key]; // this friend is offline because connId is set to -1 if (f["connId"] == -1) { o.innerHTML = "offline"; } else { o.innerHTML = "online"; } } break; } case chat.FRIEND_ONLINE: { // called when friend comes online var o = document.getElementById(arg.friend + "_status"); if (o != null) { o.innerHTML = "online"; } break; } case chat.FRIEND_OFFLINE: { // called when friend goes online var o = document.getElementById(arg.friend + "_status"); if (o != null) { o.innerHTML = "offline"; } break; } } } chatInst = icespresso.initialize(); </script>

What this sample tries to show is that upon page load, ICEspresso Framework is initialized first. In the HANDSHAKE event that follows, we set the friend list as well as query ICEspresso Service to send us a full report of those who in the friend list.

The query result is returned to us through onFriendEvent handler with eventId set to FRIEND_LOCATION. We update the HTML element accordingly. From this point onward, when either baz or bar comes online or goes offline, the notification comes in real-time push manner as implemented in FRIEND_ONLINE and FRIEND_OFFLINE events.