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.