Question

This is a very generic question not much related to any language/protocol.

I have a desktop application and a backend that communicate via TCP. Most protocol events are paired -- request/response. For example, I say "I want to create a secret chat with a person_id" (CreateChatRequest), and the backend replies with "Ok, I have created one for you" (CreateChatResponse).

Some of the backend developers say that the client must properly handle the CreateChatResponse even if no CreateChatRequest was issued by the client. They call it flexibility. While I don't find this approach valid at all. In my opinion, there must be some new protocol event like RequestToCreateChatOnBehalfOfTheClient that can be issued by the backend any time they want and I will handle it in a very simple way -- send the CreateChatRequest as if a user would do it themselves.

Is there any book/specification that says which approach is better? Or is there no "better" approach and it all depends on how we agree on the protocol? Though I am pretty sure there must be some best practices on the protocol development and responses from the backend should not be issued spontaneously.

UPDATE: Maybe my initial post was too vague, so I'll clarify. Whenever I initiate CreateChatRequest from the client, I usually do some setup (e.g. create a widget for this chat). I do always listen for CreateChatResponses and when I receive it I check if I have a widget that I can map this CreateChatResponse to. The CreateChatResponse for which there was no CreateChatRequest is simply ignored.

Also, we have a bunch of events that the server sends without a request (there are no protocol events for requesting this at all). They are simply named differently, let's say FromServer_YourProfile that I always receive only once post-login.

The "chat" here is just an example, no need to think about some real chat that may include other participants. The overall idea is that we have let's say 100+ features that work in a Request->Response manner. And sometimes the Product/Marketing teams come up with ideas like "can we do this/that without a client change" and the backend team thinks that they can send a SOMETHINGResponse and the client will react properly. When the client does not do it they call it a bug. Likely I could have developed the client-side architecture in a way that SOMETHINGRequest only sends a protocol event to the server and the entire logic is put in the SOMETHINGResponse handler. Thus, the behavior would be more server-driven but due to network latencies I usually have to do some UI stuff immediately after/before sending the SOMETHINGRequest, thus we get back to the mapping approach, where the received SOMETHINGResponse must be mapped to the initial SOMETHINGRequest, which in turn makes supporting the unsolicited SOMETHINGResponse tricky again.

Looks like there are the following options:

  1. Whenever you develop a protocol event pair (SOMETHINGRequest->SOMETHINGResponse) you must explicitly agree on if the SOMETHINGResponse may arrive spontaneously without a client request.
  2. Whenever you develop a protocol event pair (SOMETHINGRequest->SOMETHINGResponse) you must always consider unsolicited SOMETHINGResponse arrival.
  3. In the SOMETHINGRequest->SOMETHINGResponse design the response must not arrive without a request. If you want the server to emulate the request from the client there must be a separate new FromServer_PleaseDoSomething event.
  4. There are no best practices on this, just do whatever works for you.
Was it helpful?

Solution

I would say it depends on the functional requirements more than anything else, but also what you mean by "properly handle".

If a chat can only be opened on the client after a client request (like hitting the "new chat" button), then it does not make sense to accept unsolicited create chat response. In this case "properly handling" then response is ignoring it, at least no crash.

If the backend server can open chat on the client without the client having requesting one, then "properly handling" the response is to accept is as if a request was performed.

OTHER TIPS

... the client must properly handle the CreateChatResponse even if no CreateChatRequest was issued by the client. They call it flexibility.

It has very little to do with "flexibility".
It has more to do with the nature of asynchronous messaging between client and server.

Just because the last thing the client sent to the server was a CreateChatRequest, doesn't mean that a CreateChatResponse will be the next thing received by the client. In a busy, multi-threaded system, it's entirely feasible that the client might see an exchange like this:

Send:    Put_The_Coffee_On_Request 
Send:    Send CreateChat_Request 
Receive: HTTP418_Im_A_Teapot_Response
Receive: CreateChat_Response 

The two Conversations become interlaced and the client, somehow, has to make sense of this. If the client has a single "hub" that receives all messages, then this handling stuff out of sequence is not just desirable but practically essential. This may be what the "back-end" developers, who work in exactly this way, are talking about.

For reference: RFC2324 Hyper Text Coffee Pot Control Protocol

Licensed under: CC-BY-SA with attribution
scroll top