This post takes a look on the client-server communication in terms of message-oriented architecture. There is considered how can be set end-to-end information exchange between client and server through a one request/response communication unit.
In the classical consideration when client needs something from outside then he has to ask for it. He prepares a request with a certain attributes set and sends it to server. In the next stage server receives a request. Now server can continue or reject processing this request. When accepts, a further appropriate computation is made and the outcome is then provided to the initiator. Client gets a response and a circuit is closed. This is a general look at the conversation unit between client and server. It is worth to notice that time of sending request, precedence of processing requests, time of sending response and delivery path are not specified. There are only sayings like: sends, receives, process and so on. It makes it universal communication model. This model leaves two following issues undefined: time and delivery path. The only one obvious fact is that a request has to be created and passed to server and then server could give a response for that. All what happens in the meantime is up to a concrete model specification.
Request/Response communication unit:
- Client sends a request to server
- Server receives a request
- Server sends a response
- Client receives a response
Figure 1: Client – Server Request/Response communication unit
Synchronous/Asynchronous communication model
The message oriented architecture is a solution where nodes communicate by sending messages. The key factor in this approach is an ability to communicate in an asynchronous way. This kind of information exchange gives wide possibilities to manage both time and delivery path. When a traditional synchronous model takes place, client has to wait being blocked until server replies or a timeout mechanism occurs (if applicable). It can be a significant disadvantage when request handling is a time consuming process. Assuming a case when time complexity optimization of request processing is not feasible then it is still possible to optimize time on client side. Let’s consider that client sends a wish to server and then switches back to do his work. When server will be ready then lets know requester about this fact sending a returning message. It could be seen as a great idea and be incorporated into many solutions. On the other hand expectations could be opposite, like the following: client requires to have a response to continue his work in a proper way. It does not make sense to start a new work before completing existing one. Receiving a response in an undefined time in the future is not a solution here. Even though it can be worth to have message oriented communication because of server side. Keeping a connection with requester until a complete processing will get finished may be a bottle lock. Client has to wait for a response therefore a waiting emulation mechanism could be applied on client side. It could allow server taking higher number of requests.
This leads us to the general conclusion which tells that it is not so straightforward to choose between a sync and an async solution. Mixed sync/async solution could be also right choice. This paper takes into account client-server communication activities and attempts to give a general approaches that could be considered for design message oriented products.
Sender and Receiver modules
We assumed implicitly that client can be either sync or async. The same was done with server. We also mentioned mixed modes i.e. client is sync while server is async and vice versa. In fact both client and server undertake two communication activities. Client sends a request and receives a response whereas server receives a request and sends a response. There is a need to consider all of them. We can distinguish four modules responsible for handling those activities respectively: Client Request Sender, Client Response Receiver, Server Request Receiver and Server Response Sender. These modules take into account only external communication between client and server. We do not go deeper into internal communication on client and server side.
A module is a part of a node (client/server) which takes care of an appropriate handling sending and receiving activities. In order to communication flow we can assume:
- Client Request Sender module is responsible for requesting server. Works in a sync/async mode.
- Server Request Receiver module is responsible for handling requests from clients. Works in a sync/async mode.
- Server Response Sender module is responsible for sending response. Works in a sync/async mode.
- Client Response Receiver module is responsible for receiving responses. Works in a sync/async mode.
The word send does not necessarily mean send in terms of sending a message asynchronously. It is just initiating a delivery to a destination regardless of mode.
Module’s working mode is determined by type of component which is used for this module and mode in which the module need be able to receiving messages. We consider here sync and async modes. Types of component are here an abstraction and this article does not define them. Only a simple assumption is given: module’s nature should correlate with mode and hence a component can be seen as a sync-like or as an async-like. Working mode is focused on the receiving side. For senders, working mode is determined only by component nature whereas for receivers by both component nature and mode of receiving messages.
It is important to note that a sending module has to be compatible with a receiving module. It means that sender should be able to send a message that destination is feasible to handle.
Extended Request/Response communication unit:
- Client sends a request to server in a sync/async mode
- Server receives a request in a sync/async mode
- Server sends a response in a sync/async mode
- Client receives a response in a sync/async mode
Figure 2: Client – Server Extended Request/Response communication unit
Communication unit defined in the Background section is now extended into modes. In this section we assumed that each component regardless of his mode can send message in two modes. Finally, there are sixteen different configuration of senders and receivers when considering their modes. It comes from:
two modes of Client Request Sender and two modes of Server Request Receiver and two modes of Server Response Sender and two modes of Client Response Receiver. This conjunction is counted as 2x2x2x2=2^4=16.
Sender – Receiver configurations
When looking only on sender – receiver communication, there are four configurations:
1. sync sender – sync receiver
Traditional synchronous approach.
Called as request and wait for full response.
Example: Client Session Bean invokes business method on an another Server Session Bean.
2. sync sender – async receiver
Client can use this approach when he does not need to have a response to continue his work.
Called as request and do not wait (Fire and forget in some cases).
Example: Client Session Bean sends a message targeted to Server Message Driven Bean.
- Time optimization on client side. There is an opportunity to switch context to another task on client side until a response will be delivered.
- Total number of served clients optimization. Server takes a response and passes it to further processing without keeping connection with a requester.
- Complexity in design/development.
3. async sender – sync receiver
This one has common use when an async component has a need to invoke an outer business service.
Example: Client Message Driven Bean invokes business method on Server Session Bean.
4. async sender – async receiver
Very often used in a message communication chain.
Example: Message Driven Bean sends a message targeted to an another Message Driven Bean.
This article is focused only on the endpoint communication between nodes. Delivery path is a whole path which defines a journey taken by one message. In the message oriented approach are many possibilities to realize comprehensive delivery solutions.
Time is here a subject of optimization. Message oriented architectures can significantly save time on different stages of communication thanks to flexibility in adjusting modules working modes.
This article took general overview on the end-to-end communication between client and server putting emphasis on the message oriented approach. It also gives a concept to approach different sync/async configurations. General configurations are not immediate solutions. Each configuration is a topic to further more detailed consideration and hence to be introduced into a real solution.