Using XML as an Application-Level Protocol
In one of my past articles, A Pattern/Framework for Client/Server Programming in Java, I discussed a pattern for client/server development using java. That article does not answer exactly how the two parties, client and server, communicate with each other. We require an application-level protocol to do the talking between two entities. It sets up rules about how the two applications/entities communicate and understand each other over a network. If you happen to know the TCP/IP networking model or the OSI networking model, you will observe that network-based communication is implemented in layers, with the application layer at the top and the physical layer at the bottom. This article discusses issues you must face when implementing an application-level protocol and how XML proves to be an excellent choice to represent and implement the application-level protocol.
Once you decide that you need some sort of client/server model to solve your software problem, you need to think about some sort of message passing between the intended parties, so that they can understand each other. Both parties must agree upon certain rules that will be implemented by the both software entities to understand the communication going on between them. The key elements of any protocol are syntax, semantics, and timing. The syntax is the format of the protocol, semantics is the control information and error handling, and timing is the sequencing of data. While all three deal with all layers of a networking model accordingly, at the application level, we are often interested in the syntax of the protocol.
You must keep some solid points in mind when designing the application-level protocol. These points are very similar to defining language rules. The main designing rules might define the application as follows:
- It must be specific enough to answer of all the needs of the intended parties' wishes to communicate.
- It must be scaleable; if new additions are required in the protocol, it should cater to those.
- It should be capable of handling the protocol syntax errors.
- It must set forth procedure rules for data exchange.
- More importantly, it should be easily programmed.
The detail discussion of designing principles and validation of protocols is out of this article's scope. However, implementing an application-level protocol is not as easy as it sounds. In a very crude way, I may say that it involves three key tasks on the receiving end. These tasks are:
- The application has to pick data from the network stream from the lower layer, rather than the application layer.
- It has to parse the data.
- Then, it has to make decisions based on that data.
Similarly, the sending end also performs tasks in a similar way:
- It has to create the data to be sent over the network stream according to the rules of protocol.
- It sends the data over the network stream by handing over the data to the lower layer, rather than the application layer.
The sending and receiving of data over the network layer is normally efficiently handled by the library routines provided by the operating system; all the application really has to do is to create the data to be sent, and then parse the data received. This, however, seems very easy, and even sometimes is implemented very easily, but it has to be really carefully done if one wants to achieve the designing goals of a protocol.
Let us consider a very simple example of how one may design a protocol to be used by two entities. For the sake of example, let's say that this is a typical chat client/server application.
It may be decided as the client connects with the server, it tells the server the user name. The server replies whether it is already taken or not. The client resends it if required, and it receives a list of current users on the system. Then the user sends a message to any of the clients listed. He can receive messages from other clients as well. The server tells all other clients if any client leaves the server. These might be the minimum requirements by a chat client/server application; a full blown chat protocol requires a very large grammar; just peek out at the RFC for the IRC (Internet Relay Chat). A typical message passing might be generated as follows:
Client messages are in blue; the server messages are in red. All the messages end with a typical carriage return followed by a line feed.
USER: anonymous ERROR 1: Nick already registered, Please choose another nick USER: x SUCCESS: Nick x registered successfully USERLIST: x, Alpha, Romeo, Charlie MSG Alpha: hi alpha MSG Alpha: hi x QUIT Charlie: I am off. MSG Charlie: hi Charlie ERROR 2: Nick not found JOIN: Peter MSG Peter: Hi x, wanna chat? MSG Peter: Busy right now! QUIT: Bye cruel world
This is a very minimum, typical set of messages passing between the server and clients. For each unit of this protocol, a separate set of rules is required and describes it completely. Both parties have to write routines to generate these messages and to parse each and every message received from the other end. Having such a basic set of grammar and protocol, it is quite easy to write such routines, but it does follow some major flaws, for example:
- Additional care is required for checking the validity of each message. It is being observed that an out-of-order message that does not follow the agreed-upon rules quite often crashes the routines.
- The addition of any new grammar is not so easy. The code has to be re-written to consider any new element. It may happen that the old code just crashes if there is any change in the grammar rule, or if there's the addition of a new element.
- There is no way to tell what the format of each element at runtime is; the programmer has to publicly publish the rules of his protocol.
- For each set of protocols, parsing the implementation requires considerable productive time.
- Each client/server model's protocol requires a new set of routines to generate and parse the protocol.
The core idea is that considerable effort is required each time we implement a new client/server model and a protocol, just to handle it.
Then XML comes to the rescue. XML stands for Extensible Markup Language. It is a very powerful markup language. The beauty of XML is that it is self describing. The structure of an XML document is complete in its nature. It is an ordinary text document. Mostly it is used for describing "data." However, an XML document is also called "network ready." You will find many tutorials on the syntax of XML documents right here on www.developer.com. You will admire the fact that XML is very easy to learn.
But what does it has to offer us, the protocol implementers? One of the reasons for XML's popularity is the free availability of the XML parsers, the majority of which are written in Java and available at no cost at all on the Web. They are also available at no cost for other languages such as C/C++, Python, and so forth.
This allows the programmer to free himself from parsing and validating the protocol.
The structure of an XML document allows for the addition of new elements—nodes, more appropriately—without affecting the existing data. The parsers are able to just ignore the information which is not required by the programmer, and they extract only the required information. Any additions to the protocol's grammar using XML does not allow the old code to crash; at the same time, it easily implements the new code. For example, the previously mentioned chat protocol might be implemented as follows using XML:
<USER action=register>anonymous</USER> <ERROR id=1> Nick already registered, Please choose another nick</ERROR> <USER action=register>x</USER> <SUCCESS>Nick x registered successfully</SUCCESS> <USERLIST><nick>x</nick><nick>Alpha</nick><nick>Romeo</nick> <nick>Charlie</nick></USERLIST> <MSG to=Alpha>hi alpha</MSG> <MSG from=Alpha>hi x</MSG> <QUIT nick=Charlie>I am off.</QUIT> <MSG to=Charlie> hi Charlie</MSG> <ERROR id=2> Nick not found</ERROR> <JOIN><nick>Peter</nick></JOIN> <MSG from=Peter> Hi x, wanna chat?</MSG> <MSG to=Peter> Busy right now!</MSG> <QUIT> Bye cruel world</QUIT>
The next part consists of generating the XML document. Although the bare coding for generating the XML document is easy enough, many XML APIs allow a very easy and quick generation of an XML document. One of these APIs is an open source project named DOM4J, available freely from their Web site www.dom4j.org. Other such APIs are available from SUN, IBM, and many other vendors; most of them are free of cost.
One of them uses of these APIs to allow the XML document to be returned as a String object; after that, it is easy enough to send it over a network stream. The use of these APIs ensures that the effort for generating the protocol and parsing the protocol is reduced to null, thus allowing the program to concentrate on what to do with the data received from the network stream.
The XML is also being used as an application-level protocol publicly; the XHTML and WAP (Wireless Application Protocol) are two of the most common examples of such use. It seems that, in the near future, many standard application-level protocols will be re-written in XML.
I hope that this article provides you with some basic ideas about using XML for your future application-level protocol implementation. I will be waiting for your feedback on the article.
Mohammad Ali Jinnah University