Category Archives: Jabber

Instant Messenging with ColdFusion, Jabber and Smack

I noticed a couple different people wanting information on instant messenging with ColdFusion and then in another place instant messenging with Jabber and ColdFusion in the last couple days (for reasons beyond me) [first on cfguru, then on my blog, then on the jive software forums]. For those that care I put together a quick and ugly web-based instant messenging interface to Jabber using an open source Java library called Smack. You can download the source code at the end of this article or follow along as I describe the process.

Setup: 1) You need to download the Smack library and place the smack.jar and smackx.jar files into a directory acccesible to ColdFusion (commonly /WEB-INF/lib/). 2) You need to setup a couple Jabber accounts. You can either download, install and run your own jabber server or create a free account on jabber.org (or one of the many other public jabber servers). 3) You need to get a Jabber client (I’m using Exodus).

There are 2 (technically 3) parts to the interface. The easiest is a standard Application.cfm that creates an application that enables us to use sessions. You need sessions because you need to be able to persist the Jabber chat and connection objects across requests.

The second part is composed of 2 documents: a) the default page that presents a form for sending a message and has an iframe to hold the conversation and then b) the iframe that holds the conversation and then initializes the Jabber connection and chat objects. I’ll show the iframe first.

The iframe is split up into 2 parts: initialization and display. The first thing it does is check to see if the connection object exists in session scope:

// if no connection exists, create one
if (NOT structKeyExists(session, "connection")) {

If the connection doesn’t exist, the following block of code is run:

// create a connection to the jabber.org server
XMPPConnection = createObject("java", "org.jivesoftware.smack.XMPPConnection").init("jabber.org");
// login to the jabber server
login = XMPPConnection.login("username", "password");
// create a chat w/ another user
chat = XMPPConnection.createChat("user@domain.com");
// store the connection and chat objects in session scope
session.connection = XMPPConnection;
session.chat = chat;
// init an empty string to hold the conversation
session.conversation = "";

The block above creates a Smack XMPPConnection to the Jabber server (in this case I’m using ‘jabber.org’, but you should change this to be whatever server you have an account on). Next I call the login(username,password) method to login to the Jabber server and then I create a Smack Chat object by called the createChat() method on the connection. Because I need the chat and the connection to persist (in order to chat with someone), I store both in session scope. Finally, I create a session variable called ‘conversation’ that will store the conversation between the 2 chatting clients.

If the connection already exists in session scope, another block of code is run:

// get the connection & chat objects from the session
connection = session.connection;
chat = session.chat;
// retrieve the message using pollMessage() (which is nonblocking)
nextMessage = chat.pollMessage();
// if no message exists 'nextMessage' will be undefined (I think 'null' technicall)
if (IsDefined("nextMessage")) {
  // message does exist, add it to the conversation
  session.conversation = session.conversation & "<br /><strong><font color='blue'>" & chat.getParticipant() & "</font></strong> : " & nextMessage.getBody();
}

I retrieve the Smack XMPPConnection and Smack Chat objects from the session, and then call the pollMessage() method on the chat object. It’s important that I use the pollMessage() method instead of the nextMessage() method because the pollMessage method is non-blocking, it won’t wait until a message shows up from the person I’m chatting with, it returns immediately if no message exists. If the pollMessage() method returns a Smack Message object (which in Java will either return a Message or null), then I add the message to the conversation and finally display the conversation:

writeoutput("<html><head><title></title>");
writeoutput("<META HTTP-EQUIV='Refresh' CONTENT='1'>");
writeoutput("</head><body>");
writeoutput(#session.conversation#);
writeoutput("</body></html>");

You’ll notice that I’m having the iframe page refresh itself every 1 second, it would probably be better to use some JavaScript and a one pixel image to do the trick, but this works for now.

The last step is to create the page that holds the iframe and that presents the form for sending a message. The iframe is simple:

<iframe src="frame.cfm" name="chatwindow" id="chatwindow" width="800" height="500" marginwidth="5" marginheight="5"></iframe>

and then some code to handle a form post, retrieve the chat and connection objects from session scope, send the message to Jabber and then add the message to the conversation:

// if we have a form post
if (IsDefined("form.formPosted")) {
  // grab the connection and chat objects from the session
  connection = session.connection;
  chat = session.chat;
  // send the message via the chat object
  chat.sendMessage(form.message);
  // append the message to the conversation
  session.conversation = session.conversation & "<br /><strong><font color='red'>" & connection.getUser() & "</font></strong> : " & form.message;
}

Finally, a short form for entering the message:

<form action="#cgi.script_name#" method="post">
<input type="text" name="message">
<input type="submit" name="newmessage" value="Send Message">
<input type="hidden" name="formPosted" value="1">
</form>

That’s all there is too it!

You can download the source code for my examples here:

source code

I’d love your feedback on the code (if you use it) and I’d love to hear how you’re using instant messenging with ColdFusion, if you’re so inclined.

Screenshots:

Instant logging: Harness the power of log4j with Jabber

IBM developerWorks has a great article that talks about extending log4J to with Jabber. log4J comes with appenders for Sockets, JMS, SMTP, Telnet and so on… This article discusses extending the AppenderSkeleton class to provide logging to a Jabber server, which initially sounded crazy (why would you want to get IM’ed every time a log() message is fired in your application?), but makes great sense now that I think about it. You can log to a group chat room (multiple people can be viewing the logs in real-time), Jabber clients are ubiquitious across operating system and device type, and Jabber provides resource awareness, which means that the logging messages will be routed to the best resource available.

The authors use Smack by Jive Software for connectivity through Java.

v9 of Jabber Journal

v9 of Jabber Journal is out.

If you would like to learn from key Jabber contributors in person, mark your calendar now for the O’Reilly Open Source Software Convention 2003 in Portland, Oregon (July 7-11). There will be Jabber presentations by Jeremie Miller, Harold Gottschalk, and yours truly, a half-day Jabber tutorial by Ryan Eatmon and Peter Millard, and a talk by longtime Jabberites DJ Adams and Piers Harding. Thanks to generous support from Jabber Inc., the Jabber Software Foundation will host a booth on the convention floor where we’ll be spreading the Jabber gospel to anyone who will listen (let us know if you’d like to demo your software there). And you can be sure that the many Jabber developers in attendance will be holding enough late-night hackfests to really help you get in touch with your inner geek. Don’t miss it!

I’m going to be in Portland in July for a wedding on the 12th. OSCON would make having to wear a suit worth it! 🙂

The future of instant messaging

Rafe postulates on the future of instant messaging. “A Microsoft product manager says that the future of IM is all companies managing the identities of people inside their organization, and the usage of a clearinghouse to broker connections between organizations.” Of course, this is *exactly* what Jabber does. A Jabber server is exactly analogous to an email server. Each email server is responsible for one or more domains, email clients connect to email servers. A Jabber server is responsible for one or more domains, Jabber clients connect to Jabber servers. And just like email, the protocol is open for anyone and everyone to use and implement.