Spring websockets Broken pipe & client not receiving messages
<p>I have a few problems with using websockets:</p>

<ul>
<li><code>java.io.IOException: Broken Pipe</code></li>
<li>Client doesn't receive messages
<hr>
<b>TL;DR</b>  </li>
</ul>

<p>Main things I want to know:</p>

<ul>
<li>Please list all possible scenarios why the client side closes the connection (apart from refreshing or closing the tab).</li>
<li>Can a Broken Pipe Exception occur, apart from the server sending a message to the client over a broken connection? If yes, then how?</li>
<li>What are the possible scenarios why a server doesn't send a message, although the server does send heartbeats? (When this happens, I need to restart the application for it to work again. This is a terrible solution, because it already is in production.)</li>
</ul>

<p><hr>
I have a <code>SpringMVC</code> project that uses <code>websockets</code>; <code>SockJS</code> client side and <code>org.springframework.web.socket.handler.TextWebSocketHandler</code> server side.</p>

<p>A <code>JSON</code> is generated server side and send to the client. Sometimes, I get a <code>java.io.IOException: Broken Pipe</code>. I googled/StackOverflowed a lot and found too many things I don't understand, but the reason is probably the connection is closed client side and the server still sends a message (for example, a heartbeat). Does this sound okay? What are other causes for this exception to arise? What are the reasons for the client side to close the connection (apart from refreshing or closing the tab)?</p>

<p>Also, sometimes the client side doesn't get any messages from the server, although the server should send them. I log before and after sending the message, and both log statements are printed. Does anyone has an idea why this can occur? I have no errors in the console log of Chrome. Refreshing the page doesn't work, I need to restart the spring project...</p>

<p>If you need more info, please leave a comment.
<hr>
<b>Client side</b></p>

<pre><code>function connect() {
    var socket = new SockJS('/ws/foo');

    socket.onopen = function () {
        socket.send(fooId); // ask server for Foo with id fooId.
    };

    socket.onmessage = function (e) {
        var foo = JSON.parse(e.data);
        // Do something with foo.
    };
}
</code></pre>

<p><b>Server side</b><br>
Service</p>

<pre><code>@Service
public class FooService implements InitializingBean {
    public void updateFoo(...) {
        // Update some fields of Foo.
        ...
        // Send foo to clients.
        FooUpdatesHandler.sendFooToSubscribers(foo);
    }
}
</code></pre>

<p>WebSocketHandler</p>

<pre><code>public class FooUpdatesHandler extends ConcurrentTextWebSocketHandler {
// ConcurrentTextWebSocketHandler taken from https://github.com/RWTH-i5-IDSG/BikeMan (Apache License version 2.0)

    private static final Logger logger = LoggerFactory.getLogger(FooUpdatesHandler.class);
    private static final ConcurrentHashMap&lt;String, ConcurrentHashMap&lt;String, WebSocketSession&gt;&gt; fooSubscriptions =
            new ConcurrentHashMap&lt;&gt;();

    public static void sendFooToSubscribers(Foo foo) {
        Map&lt;String, WebSocketSession&gt; sessionMap = fooSubscriptions.get(foo.getId());

        if (sessionMap != null) {
            String fooJson = null;
            try {
                fooJson = new ObjectMapper().writeValueAsString(foo);
            } catch (JsonProcessingException ignored) {
                return;
            }

            for (WebSocketSession subscription : sessionMap.values()) {
                try {
                    logger.info("[fooId={} sessionId={}] Sending foo...", foo.getId(), subscription.getId());
                    subscription.sendMessage(new TextMessage(fooJson));
                    logger.info("[fooId={} sessionId={}] Foo send.", foo.getId(), subscription.getId());
                } catch (IOException e) {
                    logger.error("Socket sendFooToSubscribers [fooId={}], exception:  ", foo.getId(), e);
                }
            }
        }
    }
}
</code></pre>