Disconnects are normal
Treat disconnects as normal rather than exceptional, because a connection meant to live for hours will lose them. Laptops sleep, phones hop from wifi to cellular, balancers recycle.
This is the only technique in the section that ships recovery inside the protocol instead of leaving it to you.
Two fields do the work. Your server can say how long to wait before reconnecting, and it can tag every event with an identifier.
The browser remembers the last identifier it processed, and when the connection drops it reconnects on its own and presents that identifier in a header. Your server reads it, looks up everything the client missed, replays it in order, and resumes streaming live. Your client code does not change at all, and the resume is invisible to it.
The replay buffer
Build the replay buffer, because that header only helps if your server can answer it. Your events need to live somewhere you can query by identifier for at least as long as a realistic disconnect. That means identifiers which only ever increase, backed by a ring buffer or a log.
Size that buffer in time rather than in messages. Surviving a two minute wifi handoff means holding two minutes of events for your busiest stream.
Decide explicitly what happens when the buffer cannot help, like a client coming back after a six hour laptop sleep with an identifier that aged out long ago.
Send a resync event telling that client to refetch the current state normally and then stream from now on. Skip this design step and your dashboards go quietly wrong for everyone who shut a laptop over lunch, and nobody files a bug because nobody notices.
Worked example
Tara's team ships a fleet dashboard streaming truck positions over SSE without event ids. Dispatchers report trucks frozen on the map after lunch: laptops sleep, EventSource reconnects on wake, but the stream only sends changes going forward, so any truck that moved during the nap stays stale until it moves again. Tara adds id: lines carrying a global sequence number and backs the stream with a Redis Stream, an append-only log in memory, holding 15 minutes of events, about 40,000 entries at their volume. On reconnect the server reads from Last-Event-ID forward and replays the gap in order. For sleeps longer than the buffer, the server sends a resync event and the client refetches a position snapshot, one 80 KB request. Frozen-truck tickets drop from a few per week to zero.