Creating A Mobile JavaScript Chat – Part 1: The Service
In this series, we will be creating a simple JavaScript mobile chat application. It can be both used from a desktop browser as a web page, and from a handheld device as an application.
Keep in mind that this tutorial is just a demo, showing the bare bones of the process. The final application we create will be using text files as a persistence layer. It is not aimed to be used in a production environment.
Here are further things that can be done to make the app ready for production use.
- Using nicknames (our demo simply posts text messages without indicating who sent what),
- Using a database (or the cloud) as the persistence layer,
- Creating some kind of registration, and guest access for non-registered memebers,
- Timestamps for messages,
- Showing only the messages that are sent after the user logs in (our demo will show everything old and new)
- Private chats…
That’s just a minimum set
Some other “nice to have”s include: Facebook connect, integrating other IM protocols such as MSN, or Yahoo!, sending and receiving files, sharing state across tabs and pages, using a robust chat server (such as ejabberd) to enable scaling up, video chat… The list can go on and on…
We may revisit our chat application in the future to add some of those features, who knows
Anyway, every journey starts with a single step.
So let us begin our journey by creating a server interface:
Globals
Let’s define some globals that we’ll be using throughout the application.
//chat_common.php
// Global constants:
$CHAT_KEY_MESSAGE = 'message';
$CHAT_KEY_LAST_INDEX = 'lastIndex';
$CHAT_DATA_FILE_NAME = dirname(__FILE__) . '/data.txt';
$CHAT_CONNECTION_TIMEOUT = 25;
// Utility methods:
/**
* Returns the value of matching key from $_GET,
* returns the default value otherwise.
*/
function get($key, $default = '') {
return isset($_GET[$key]) ? $_GET[$key] : $default;
}
Comet Busy-Wait Cycle
A Comet Service is nothing but a connection kept open unless something new happens:
Here’s a simple implementation that flushes the open connection either a timeout occurs, or some new data is added to the persistence layer (i.e. the data.txt file, in our case):
<?php
//chat_comet.php
include('./chat_common.php');
...
function page_load() {
global $CHAT_DATA_FILE_NAME;
global $CHAT_KEY_LAST_INDEX;
global $CHAT_CONNECTION_TIMEOUT;
//chat lines
$lines = get_lines();
// How many lines are there in total.
$lineCount = count($lines);
// The last sequence number retrieved in that session.
$lastIndex = get($CHAT_KEY_LAST_INDEX, 0);
// Used for detecting connection timeout.
$startTime = $currentTime = time();
// Used for detecting file changes.
$startModified = $currentModified = filemtime($CHAT_DATA_FILE_NAME);
$isNewData = ($lineCount - 1 > $lastIndex);
// if there is unread data, flush immediately.
if($isNewData) {
flush_buffer($lines, $lastIndex);
die();
}
//busy-wait
while(true) {
// Give some breathing time for the CPU.
usleep(10000);
// Reset file statistics.
clearstatcache();
$currentTime = time();
$currentModified = filemtime($CHAT_DATA_FILE_NAME);
$isFileModified = ($currentModified - $startModified > 0);
// Someone else has modified the file, get contents and flush.
if($isFileModified) {
$lines = get_lines();
break;
}
$isResponseTimedOut = ($currentTime - $startTime > $CHAT_CONNECTION_TIMEOUT);
// Nothing special, break and give a default response.
if($isResponseTimedOut) {
break;
}
}
flush_buffer($lines, $lastIndex);
die();
}
page_load();
?>
I believe the comments are self-explanatory.
The page_load function is fired on page load, as its name implies
And here are the helper functions get_lines and flush_buffer to complete:
function flush_buffer($lines, $lastIndex) {
global $CHAT_KEY_LAST_INDEX;
global $CHAT_KEY_MESSAGE;
$response = array();
$response[$CHAT_KEY_MESSAGE] = array_slice($lines, $lastIndex);
$response[$CHAT_KEY_LAST_INDEX] = count($lines) - 1;
echo json_encode($response);
flush();
}
function get_lines() {
global $CHAT_DATA_FILE_NAME;
return explode(PHP_EOL, file_get_contents($CHAT_DATA_FILE_NAME));
}
Sending a Message
That was for the “listening” part. But chat is a two-way communication and we need an endpoint to persist messages. That’s the easier part
:
//chat_send.php
/*
* Sends a message via GET request.
* chat_sendmessage.php?message={the_message}
*/
include('./chat_common.php');
// Add avnew message, if any.
$message = get($CHAT_KEY_MESSAGE, '');
if ($message != '')
{
// Exclusively lock file to avoid race conditions.
file_put_contents($CHAT_DATA_FILE_NAME, $message.PHP_EOL, FILE_APPEND | LOCK_EX);
}
echo '1';
die();
Some Questions for the Curious
That’s all for this section. Hope it was useful
And here are some followup questions for further investigation:
- Do you think the service can be improved? If so, how?
- Any performance implications of keeping an HTTP connection open for a long time?
- What is the best server (apache, nginx, lighthttpd, M$ IIS) for a comet service, and why?
- Is this chat comet service secure? Well I don’t think so
.
Definitely its vulnerable to an XSS injection.
So how can we make it more secure? — any ideas?
In the next part of the series, we will be designing a chat client that consumes this comet service, and uses the chat_sendmessage endpoint to send a message.
In the meantime, feel free to share your comments, ideas and suggestions


As you already know, if you use the ubiquitous Apache setup for comet-y things, you’d be out of available max. connections real fast in a production environment
Since our subject is js, what about node.js? It uses Javascript at server-side too
Hi Halil,
Thanks for your comment.
You are totally right. It will not matter much for a simple demo application where the only IO operation is reading and writing to a static file. (though when the number of concurrent connections reach a few thousands, using an event-based approach will definitely make a difference since even a few milliseconds spent on the blocking IO operation matters “a lot“)
Apache has been around quite a while, and it’s pretty much the web server that everyone uses. Apache runs in the traditional fork/exec model. Which is not optimal for a large number of parallel connections, which heavily-loaded comet applications require by definition.
Here’s a slightly outdated, yet useful, article on blocking versus non-blocking IO http://www.kegel.com/c10k.html
node.js is an event-driven alternative to that problem. It uses an event-based non-blocking approach for IO operations. ( http://en.wikipedia.org/wiki/Asynchronous_I/O )
Though it’s not the only solution. lighthttpd, for instance, has a very small memory footprint and also has an event-driven architecture. Also Nginx works great for especially serving static content (which is the file we constantly read, in our example)
In an event-driven server architecture, even when the connection between the server and client is kept open for a long amount of time, the server can still continue serving other clients without having a need to spawn another thread.
This is done by using an event queue which is very much analogous to the threading queue that’s used for COM ojbects in Single Threaded Apartment mode ( http://msdn.microsoft.com/en-us/library/ms693344(VS.85).aspx )
Here’s a very simplified flow:
- client asks server for some data.
- server tells client to wait, triggers an event to complete the client’s request,
- server then continues to serve other clients,
- when the event completes, the result is sent to a queue and delivered to the client when it’s turn comes.
(Dan York, describes that it’s just like a fast-food restaurant: http://code.danyork.com/2011/01/25/node-js-doctors-offices-and-fast-food-restaurants-understanding-event-driven-programming/ )
The solution is not a cure for all. Under very high load the event queue will be populated too much and response times may suffer.
If the event queue starts getting too long, you can certainly add an additional nodes, but you don’t need to do so at quite the rate of a thread-based system.
What makes node.js appealing to me it its JavaScript syntax that’s used when creating events and callbacks. You write JavaScript on the client-side and on the server-side. It’s a great thing for a JavaScript-lover like me
May be I’ll write a node.js application of this chat server in a future tutorial
Cheers.
By the way, the “event driven” software architecture is also known as the “Hollywood pattern”:
“Don’t wait; we’ll call you back
”
Cheers.
Thanks for the extensive background clarification
One intriguing thing about node is that you write both the server and the app in Javascript and go (e.g. you don’t need a PHP/Python/Ruby CGI wrapper). Of course, having the flexibility of using your favorite/actual programming language is the pro of other solutions (nginx, lighty, …).
We’ll be looking for your future tutorials
Definitely, it makes Node.js far more appealing
Actually server-side JavaScript has been around for some time:
In former SSJS implementations, JavaScript was the “raison d’être”, and the common approach was to focus on translating best practices from other platforms like Ruby, PERL and Python, into JavaScript.
On the contrary, Node.js took a leap from this.
imho, other than the ubiquity of JavaScript, there are three factors contributing to Node’s success:
1. Node.js makes event-driven I/O Programming, the best way to do I/O Programming, much easier to understand and achieve than ever before.
2. Node.js does not try to solve all problems. It lays the foundation and supports the basic internet protocols using clean, functional APIs.
3. Node.js does not try to be compatible with pre-existing software, it takes a fresh look at what many believe is the right direction.
… and more tutorials are on the go
pls..help!!!..i dnt understand anything you guyz are saying.can u just start from the software to download, the first thing to do..it will realy help tanx
Hi jethro,
I’m taking my notes on this, and will put a more explanatory mobile-web-dev 101 post when I have time.
In the meantime you can STFW and read the getting started guide in PhoneGap wiki.
Hope that helps,
Volkan
please volkan, i realy need your help. I want to learn j2me coding, i dont know if you can help me. Or if can me with a j2me chatting app code that will look whatsapp or 2go messange for my project in school. Pleasssss… Help me.
Dear olahmen,
Since it is your “school project”, “you” are responsible for learning whatever necessary to complete your project.
Googling “j2me tutorials” will give you a bunch of links to start with.
I’d love to hear about your research and findings.
Good luck with your project.