1

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.
5
  • So is the question if the listeners you create can use CreateChatResponse as the message? Personally I don't see why not. But you cannot handle it unless you listen for it. Jan 25, 2021 at 14:45
  • 2
    What would "properly handle" mean in this context? Doesn't that mean to ignore that response, since no CreateChatRequest event was issued? So why should it be a problem to ignore such unexpected events? Please clarify.
    – Doc Brown
    Jan 25, 2021 at 15:02
  • Can you tell an unsolicited CreateChatResponse message apart from a response to a request? You will have to consider message-crossing scenarios like where the client sends a request and then receives an unsolicited CreateChatResponse relating to a different chat. Jan 26, 2021 at 10:57
  • Okay, so I create a chat with you. I send a CreateChatRequest, and I receive a CreateChatResponse. What about you, the person who did not create a chat, but is now part of the chat that I opened? What I'm suspecting here is that the backend is designed to send the same CreateChatResponse to you, because you are a participant in a created chat - even though you were not the one who created the chat. It might use a CreateChatResponse as the trigger to open a chat (on both ends). If this is how the backend works, the backend team's advice makes sense.
    – Flater
    Jan 26, 2021 at 11:42
  • 1
    There is no braindead "best practice" you can refer to when arguing with your backend team. However, if you are looking for a strategic advice: try to avoid request/response pairs in event based protocols. Some of them have their place, of course, but lets take "Chat" as an example: chat can be perfectly created around unidirectional messaging, no need to have all chat messages bidirectional in a requestt/response manner.
    – Doc Brown
    Jan 28, 2021 at 14:44

2 Answers 2

2

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.

0

... 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

1
  • 1
    Figuring out which response belongs to which request is the responsibility of the client and how all asynchronous systems work. But that is not relevant for OP's question, as it is not the same as having the ability to receive responses to requests you never even sent or knew of - which is what OP is being asked to implement. Take your example and just remove Send CreateChat_Request from it. Does the response still make sense when there is no related request?
    – Flater
    Jan 26, 2021 at 13:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.