A quick way to see which layer is failing: open the browser's network tab, filter to the WebSocket or event-stream connection, and watch it.
You will see either the handshake failing outright: which points at the upgrade headers - or the connection establishing and then closing after a consistent interval, which points at a timeout, and the interval tells you whose timeout it is.
That single observation separates the two main causes without changing anything.