The "M" in XMPP stands for "messaging", and exchanging messages is one of the core uses of an XMPP library like CAXL. In XMPP, messages come in several flavors, denoted by the 'type' attribute on the <message/> element. The simplest is type "normal", which is a kind of fire-and-forget message to which you don't necessarily expect a reply. Slightly more advanced is type "chat", which is used in one-to-one chat sessions between two entities. Additional message types include "groupchat" (discussed in the next chapter) and "headline" (discussed in the chapter after that). In this chapter, we first talk about the basic mechanics of sending and receiving messages, then explore two concepts related to one-to-one message exchanges: chat sessions and chat states.
In CAXL, you can create XMPP messages using the jabberwerx.Message
object. This object has several methods that correspond to standard child elements of the <message/> stanza defined in RFC 6121:
The jabberwerx.Message
object also inherits the methods defined for the jabberwerx.Stanza
object, which means you can set the message type as well.
mymsg = new jabberwerx.Message(); mymsg.setBody("Hello World"); mymsg.setType("normal");
Naturally, there are also equivalent methods for retrieving the body, subject, and thread for a message (getBody()
, getSubject()
, and getThread()
).
Once you have constructed a message, you can send it using the sendMessage()
method on the jabberwerx.Client
object.
client = new jabberwerx.Client(); mymsg = new jabberwerx.Client(); mymsg.setBody("Hello World"); mymsg.setType("normal"); mymsg.setTo("jwtest0@example.com"); client.sendMessage(mymsg);
However, in practice we typically send messages in the context of a chat session (see below) or a multi-user chatroom (see Chapter 6), so you probably won't use Client.sendMessage()
directly. Now let's see how the chat controller provides methods for sending and receiving one-to-one messages.
Although XMPP enables you to send a single message, most interactions between instant messaging users occur in bursts: you might not chat with someone for a few hours or a few days, but then exchange a fair number of messages over the span of several minutes. Such an exchange is called a chat session.
CAXL supports chat sessions through the ChatController class, which controls the creation of ChatSession objects. A ChatSession can be created directly using the openChatSession()
method by specifying the JabberID with which to chat:
var client = new jabberwerx.Client(); var chatController = new jabberwerx.ChatController(client); var chatSession = chatController.openSession("user@example.com");
The openSession()
method also takes an optional thread
argument. In CAXL this is not really necessary, since CAXL allows only one chat session per recipient JID at any one time.
Once you have instantiated a chat session with a contact, you can send messages within that session using the sendMessage()
method:
chatSession.sendMessage("Hello World");
There are several events related to chat sessions. If you receive a message from another user, a new ChatSession object is created on your behalf and the chatSessionOpened
event is fired. Of course, this event is also fired if you call the openSession()
method on the ChatController.
Typically you will want to bind the chatSessionOpened
event on the ChatController and extract the ChatSession object from that event data:
chatController.event("chatSessionOpened".bind(function(evt) { var chatSession = evt.data.chatSession; });
However, just finding out about a chat session is not all that useful. You also want to find out about each of the chat messsages you receive in the course of that session. You can do this by binding the chatReceived
event on the chat session and most likely displaying to your user both the sender of the message and the message body (extracted using the getFrom()
and getBody()
methods on the message):
chatController.event("chatSessionOpened".bind(function(evt) { var chatSession = evt.data.chatSession; chatSession.event("chatReceived").bind(function(evt) { var message = evt.data; var sender = message.getFrom(); var themsg = message.getBody(); // display sender and message body to the user }); });
You probably also want to know when a chat session ends. This is done by registering for the chatSessionClosed
event. This way, if your conversation partner terminates the session or the closeSession()
method is invoked on the ChatController, your client can react appropriately, for example so that you can change an indicator or close a tab.
Within a chat session, it can be helpful to know if your conversation partner is paying attention, is actively typing a reply, has temporarily paused composing, has become inactive, or has gone away entirely. XMPP includes a protocol extension called Chat State Notifications (
In CAXL, chat state notifications are enabled by default, since the boolean sendChatStates
field on the ChatController object defaults to true. If you want to disable chat state notifications, you can set this field to false:
var chatController = new jabberwerx.ChatController(client); chatController.sendChatStates = false;
You can find out about chat states by binding the chatStateChanged
event to the relevant chat session. The event data consists of a JID (null if you triggered the event) and the new state, which is one of "active", "composing", "paused", "inactive", or "gone" (see XEP-0085 for a detailed description of these states). Here is an example:
chatController.event("chatSessionOpened".bind(function(evt) { var chatSession = evt.data.chatSession; chatSession.event("chatStateChanged").bind(function(evt) { var thestate = evt.data; var sender = thestate.jid; var state = thestate.state; // display the state of the sender, perhaps with different colors }); });
© 2012 Cisco Systems, Inc. All rights reserved.