Here’s a demonstrative scenario:
- Server sends A to client
- Client receives A, sends Ack(A)
- Ack(A) gets lost
- Server is sitting there tapping its foot waiting
- Server decides A may have been lost, and sends again as A2
- Client gets A2 again and Ack(A2)
If you fired an event saying that A was lost… that wouldn’t be accurate. A wasn’t lost, the client got it just fine the first time, it was the Ack(A) that was lost.
Normally there are some interesting techniques used to combine together the acks and messages in an optimal way that gives the best user experience. For example, if the Client above also had to send e message to the server it might send message B + Ack(A) in the same packet. There’s also decisions to make on whether to prioritize a resend over additional new sends.
Long story short, each individual message can’t be taken in isolation, the connection between client and server is a continuous stream and decisions on what to resend / when aren’t as simple as “resent message X after Y”.