Clients never exchange messages directly with each other. Instead, as pointed out in "Architectural Overview," clients send messages to each other through their servers. This is done primarily to protect each user's privacy, but it is also necessary in order to provide presence detection services for users with dynamic IP addresses and to facilitate advanced features, such as off-line message receiving and off-line property publication.
Functionality is provided in the client/server protocol whereby the client can ask its own server to deliver any message to another client's server. For more information, see:
Because servers dispatch messages asynchronously and by means of UDP, it is possible that some messages will be lost or delivered out of order. Because of this, each message must carry sequencing information so that lost or out-of-order messages can be detected.
Messages are sent in a special data structure called "envelops." The details of this data structure are given later in "Message Envelops." For now, suffice it to say that these envelops are simply wrappers for the message text being sent.
When instant message envelops are sent, it is recommended that they contain, however they are encoded, sufficient information to detect missing or out-of-order messages. How this is done depends on the encoding scheme, but the following principles are recommended as a general guidelines.
Instant messages should be sequenced using a (session ID, sequence number) pair. The sequence number is a monotonically increasing value indicating the order of the message, beginning with 0 and increasing by one for each outbound message. (Maintain a seperate sequence counter for each recipient.) The receiving client monitors these sequence numbers to determine whether messages are missing or out of order.
Whenever your client wishes to reset the sequence number, say, at the beginning of a new chat session, it can do so without confusing the receiver by using a new session ID. Session IDs do not need to increase monotonically or in any particular fashion; all that is required when resetting the sequence number is that you use a new session ID. Whenever a client receives a message with a new session ID, it expects that the first message sequence number for that session will be 0.
Odds are good that if you use a wide enough integer for the sequence number, you will never run out of values. (Your fingers will fall off first.) However, there are still several reasons why you would want to change session IDs. Suppose, for example, that you and your partner are chatting for the first time on Monday, and that your outgoing messages are labeled with a session ID of 1 and increasing sequence numbers. Lets further suppose that when you and your partner are finished chatting, you reboot your computer, but your client simply leaves his software running and doesn't even close the incoming message window dedicated to your messages.
Much later, on Wednesday, you decide to chat with him again. What do you do? Do you use the next sequence number based on your Monday chat, so that his client doesn't freak out over missing messages? You might, but to do this correctly your software must be capable of remembering all your old sequence numbers for all of your chatting partners. Also, you cannot predict whether your partner closed and reopened his software on Tuesday, perhaps forgetting the current sequence number.
Requiring every client to indefinitely remember the last sequence number for every partner is unreasonable. The better solutions is to begin chatting with a new session ID. It doesn't have to be the next session ID, just a different session ID. This way, your partner's software will know how to handle your message regardless of the last sequence number. If it still remembers the previous sequencing information, it will recognize the new session ID and be content with resetting the expected sequence number to 0. On the other hand, if it has forgotten everything about the previous session, then it doesn't matter anyway.
For instant messages sent in PLAIN envelops, the (session ID, sequence number) pair is contained in the data field (just after the PLAIN designator and subtype field). The sequencing pair comes first and is immediately followed by the actual instant message text. The arrangement of this data is as follows:
| offset | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ... |
|---|---|---|---|---|---|---|---|---|---|---|---|
| contents | session ID | sequence number | instant message text | ||||||||
As indicated, the sequencing pair occupies exactly the first 8 bytes of the data field, regardless of the PLAIN subtype. The sequence number is encoded using big endian byte ordering.