If you are truly into development and, especially, into web development, you definitely know what HTTP requests and responses are and how client-server communication is performed. However, in the present day, “classic” (i.e. regular) HTTP request/response traffic is just part of the whole picture of client and server communication and there are several other opportunities for this communication to be accomplished, all of which are based (at least partially) on regular HTTP or completely use it as foundation.
It can be said that a long time ago when online content used to be pretty straightforward, simple HTTP calls used to do the job. However, with years passing by, the functionality of a server providing some documents once when asked became insufficient for the needs of users. Websites went through metamorphosis and were transformed into web applications, thus exposing the requirement for client-server communication to become, let’s call it, more dynamic.
Client, Server and regular HTTP
In the world of computing, a server, as the name states, is a device with certain running software that, on invocation, provides predefined functionality for other devices and respective programs running on them called clients. The client, on the other hand, is a machine which goal is to access the services and functionalities made available by a given server. In other words, a server is responsible for making a certain service available for many clients and, if a client requests the service, it is the server that takes the responsibility to supply any of the clients with the requested resources.
As we know, web resources are structured in the form of hypertext documents (combination of text and logical links between the different nodes in the text) and HTTP is the protocol situated in the application layer of the OSI model over which hypertext data can be transferred or exchanged. So, if we imagine your laptop is the client machine, when you enter some URL in the browser, e.g. http://somedomain.com, this address is actually mapped to an IP address of a server (e.g. 192.168.123.1) located somewhere in the world. Hitting the enter key makes the client (your laptop) send an HTTP request to the server located at that IP address. The server, on the other hand, retrieves the hypertext documents representing the web service from its storage and sends them back to the client. At this point, the browser of your laptop – the client – renders the documents returned by the server and – surprise – you see the content of the web site you requested. Generally said, regular client-server communication over HTTP is performed in a synchronous manner – the client requests resources, the server calculates them, retrieves them, sends them back and closes the connection. In other words, to every client request the server sends exactly one response before closing the communication channel.
First of all, when we say AJAX, we actually refer to asynchronous client-server communication. If you come back to the previous paragraph, we said that regular communication is performed synchronously and the flow is as follows: the client sends a request, the server responds and closes the connection. On the other hand, asynchronous communication, as the name states, provides the client with the ability to invoke the server in the background, without interfering with the current state of the rendered web page. If we go into deeper details, the asynchronous client-server communication flow can be described like that: initially, the client sends a regular HTTP request (pictured above), to which the server responds with the demanded resources. Then, the returned resources, which are run on the client, depending on the action the client needs to perform, can trigger as much requests to the server as necessary without the page being refreshed. On the other side, the server begins to process the requests one by one and, whenever the response to a given request is ready, the necessary data is instantly sent back to the client just like regular HTTP traffic and the connection for the given request is closed. A simple example – we have a web page showing the current temperature in Barcelona. When we hit, e.g. www.barcelonaweather.com (I just made the name up), the server returns the initial page sources to the client (our laptop) and we can see the current temperature in Barcelona. However, in several minutes’ time or so, the temperature in Barcelona may have changed without the user being aware. For that reason, without us being required to refresh the page (i.e. manually ask the server for fresh resources), the sources initially returned to the client are programmed to trigger asynchronous requests every minute, asking the server for the current temperature. Every time the degree value is requested by the client, the server provides it and the client, respectively, updates the value we see without us doing page refresh by hand. This is AJAX explained in short and, if you are a bit confused what the name AJAX stands for, you can head down here and have a further look – for now it is important to know that AJAX is an alias for asynchronous client-server communication.
The model of communication between client and server known as long polling can be actually referred to as AJAX long polling. In other words, long polling is a sub-type of asynchronous client-server communication. So, the starting point of our explanation is the same: the client requests given resources, the server responds and closes the connection (all using synchronous regular HTTP). Then the returned resources which already run on the client side can trigger as much asynchronous requests to the server as necessary (as described above). At that point on, however, the logic changes.
When sending numerous asynchronous requests, naturally, server load increases dramatically. Don’t forget there can be services with million clients trying to reach the server simultaneously – put to that the fact that each client itself may be implemented in such a way to afterwards trigger, e.g. 1000 AJAX requests in different use-cases – it is not that hard to calculate how much that is for the server and what the overhead is.
For that reason, in such cases the long polling AJAX mechanism can be utilized. So, what is it actually?
The resources which are initially returned by the server, in the case of long polling, are programmed to trigger a single asynchronous “update” call to the server. When the server receives the request, it does not instantly try to find what is requested and respond, but rather waits until there is a whole bunch of information available (it is all up to the server) and then returns this data to the client and closes the connection. When data arrives and is received from the server, the client instantly creates a new request to the server, begins waiting for fresh updates and the loop repeats as described.
When it comes to long polling, we can say that the implementation policy for the client is “don’t ask for certain small chunks of data separately, rather constantly ask for the whole data lump you need and, when there are updates to it, it is guaranteed you will have them delivered”. By applying long polling, server load can be palpably reduced since asking for greater amount of data to be returned requires much less processing time for the server than handling requests for numerous smaller data units at a time.
Also known as HTML5 server-sent events (or event source), this type of client-server communication, although being a bit technically-specific (since it is based on HTML5), has a starting point the same as the one for long polling. However, the underlying logic of this method states the number of asynchronous calls performed by the client is not limited, but each one of them should be on a certain topic (i.e. all requests should be related to a topic and not generalized). After such a request to the server is performed, the client has subscribed and remains listening for incoming data on that topic, while the server, after receiving the topic request, constantly monitors for new events considering the topic and, if such are present, directly sends back the data considering the topic without the client explicitly asking. It is the role of the client to be ready to perform the necessary actions on each received event data. If we refer to the example with the weather in Barcelona, the client may say “hey, server, I want you to keep me updated on the topic what’s the weather in Barcelona, I’ll keep waiting for response from you”. We should note that the topics for all events requested by the client need to be mapped on site of the server (i.e. the client cannot request events on a topic that does not exist or is not handled and broadcast as a stream from the server side). Furthermore, keep in mind that a given topic can be, for example, a script running on the server. If the client does a request for events broadcast from, e.g. a script called CurrentWeatherState.php on the server, we can say that the topic of the request is “CurrentWeatherState”. The topic can also be a parameter sent together with the request – it depends on the developer’s solution how it is specified in the client and how it is handled on the server. What is important to remember is that a topic – as a term – is something abstract, can also be referred to as “subscription” and depends on the use-case and, as stated, the decision of the developer.
Server-sent events are actually a pretty nifty solution because they have the benefit of long polling – reduced server load, but also lead to smaller-sized data chunks being transported between the client and the server.
This method is also named HTML5 websockets and yet again – it is technically specific (as its name states). The starting point of our explanation is once again the same as described above. This time, however, when the client is provided with the initial resources from the server, a connection between both sides is opened. This connection remains open until either the client or the server closes it. During the time interval when the connection is open, both the sides can send data (respectively updates) asynchronously to the other party. However, there is something important to be stated here – all data is sent directly over socket rather than usual HTTP response, leaving only the initial resource loading to be transferred over HTTP. An example for websocket client-server communication are chats – all clients are always updated with what’s in the chat server, while the chat server is always up-to-date with what all clients have posted (i.e. what all chat members have written).
To summarize, I can state that none of the described methods for materializing client-server communication is a must – each one has benefits and drawbacks and whether a developer should use it depends on the concrete goal of what the implemented web service should be able to do, how big the audience using it will be, what type of server is going to be used (commercial servers cost really a lot per month, so the chance the developer will have to cope with server load problems are pretty big), etc. Furthermore, long polling, server-sent events and websockets are a matter of choice, but I don’t think pure AJAX can be avoided for a web service nowadays, or at least, the workaround may cost much greater effort, so, one way or another, you as a developer will have to adopt at least one of the listed methods. Finally, it’s important to mention that a given web service can be based not only on one of the described client-server communication methods, but can interweave and combine several, if not all of them for different use-cases – so you are never limited to stick to a single method if one of the others will fit better in a corner use-case.
Hope this overview was helpful,
wish you all the best!