Search code examples
javawebsocketspring-websocket

How to process binary messages as input streams?


I want to implement upload of large files via WebSockets and have the server store the files in a database or an object store.

I'm trying out the spring-websocket library and, as far as I understood, I need to extend the BinaryWebSocketHandler class and implement the file storage there.

public class MyWebSocketHandler extends BinaryWebSocketHandler {

    @Override
    protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) throws Exception {
          // Store file in DB/OS...
    }

}

While this looks wonderful, my problem is that the BinaryMessage I get to handle only allows me to work with ByteBuffers. I assume this means that the entire file is loaded in-memory and stored in this ByteBuffer object (unless I also override the supportsPartialMessages method, of course). Is this correct?

If yes, this would be a huge problem for me, since storing large files in-memory is not something I want to do. I was expecting to be able to get access to an InputStream and read the file from there. It also seems like this should be possible, seeing as spring-websocket uses the Java WebSocket API under the hood, and they allow MessageHandlers to handle InputStreams (see https://docs.oracle.com/javaee/7/api/javax/websocket/MessageHandler.Whole.html).

Unfortunately, I cannot find any way of getting access to an InputStream in my handler. Does anyone know whether this is actually possible? If not, would this make sense as a feature request or would this be a misuse of WebSockets somehow?


Solution

  • You can override AbstractWebSocketHandler.supportsPartialMessages, which states that:

    If this flag is set to true and the underlying WebSocket server supports partial messages, then a large WebSocket message, or one of an unknown size may be split and maybe received over multiple calls to WebSocketHandler.handleMessage(WebSocketSession, WebSocketMessage). The flag WebSocketMessage.isLast() indicates if the message is partial and whether it is the last part.

    https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/socket/WebSocketHandler.html