<story><title>Server-sent events, WebSockets, and HTTP</title><url>https://www.mnot.net/blog/2022/02/20/websockets</url></story><parent_chain><item><author>eldelshell</author><text>My experience with SSE so far (take this as recommendations if you wish)&lt;p&gt;You need to implement a server-side heartbeat feature.&lt;p&gt;You need to handle the close event from EventSource and be able to reconnect.&lt;p&gt;Tabs can be problematic. When you subscribe, you use a URL with a nominal ID to identify the client. For example, on a chat app, you would use &amp;#x2F;api&amp;#x2F;sse&amp;#x2F;userA&amp;#x2F;subscribe&lt;p&gt;Problem is, if userA starts opening tabs, each tab creates a new subscription for userA so you need to randomize each connection (userA-UUID).&lt;p&gt;If you don&amp;#x27;t use a nominal id, the server won&amp;#x27;t know to which subscriber to send the data and you don&amp;#x27;t want to broadcast all your chats.&lt;p&gt;I&amp;#x27;ve used the Broadcast channel API in conjunction with SSE to have only one tab handle the SSE connection, and broadcast incoming SSEs to the other tabs which also reduces the number of connections to the server to one.&lt;p&gt;On the server it&amp;#x27;s also a PITA because not all instances&amp;#x2F;pods have the subscribers list. The way I&amp;#x27;ve found to solve this is with clustering the instances with Hazelcast or Redis or a MQ.&lt;p&gt;But once you figure out all this, SSE works quite well.</text></item></parent_chain><comment><author>qwtel</author><text>Sounds like a service worker, for which there&amp;#x27;s only one active at a time for all tabs (and can communicate with them) could help with your client side issues.</text></comment>
<story><title>Server-sent events, WebSockets, and HTTP</title><url>https://www.mnot.net/blog/2022/02/20/websockets</url></story><parent_chain><item><author>eldelshell</author><text>My experience with SSE so far (take this as recommendations if you wish)&lt;p&gt;You need to implement a server-side heartbeat feature.&lt;p&gt;You need to handle the close event from EventSource and be able to reconnect.&lt;p&gt;Tabs can be problematic. When you subscribe, you use a URL with a nominal ID to identify the client. For example, on a chat app, you would use &amp;#x2F;api&amp;#x2F;sse&amp;#x2F;userA&amp;#x2F;subscribe&lt;p&gt;Problem is, if userA starts opening tabs, each tab creates a new subscription for userA so you need to randomize each connection (userA-UUID).&lt;p&gt;If you don&amp;#x27;t use a nominal id, the server won&amp;#x27;t know to which subscriber to send the data and you don&amp;#x27;t want to broadcast all your chats.&lt;p&gt;I&amp;#x27;ve used the Broadcast channel API in conjunction with SSE to have only one tab handle the SSE connection, and broadcast incoming SSEs to the other tabs which also reduces the number of connections to the server to one.&lt;p&gt;On the server it&amp;#x27;s also a PITA because not all instances&amp;#x2F;pods have the subscribers list. The way I&amp;#x27;ve found to solve this is with clustering the instances with Hazelcast or Redis or a MQ.&lt;p&gt;But once you figure out all this, SSE works quite well.</text></item></parent_chain><comment><author>samwillis</author><text>This chimes a lot with my experience. Although I think SSEs are brilliant if the stack I’m using supports Websockets I would probably default to them even for a simple event stream now.&lt;p&gt;To add to your list of problems, I have had memory leaks with SSE responses stuck open on the server even when the client disconnects. Resorted to killing the response on the server every couple of minutes and relying on the client reconnecting.</text></comment>