与Servlet相比,使用Websocket的文件下载速度很慢

时间:2015-04-10 09:34:51

标签: java tomcat websocket

我使用tomcat 7.0.47 WebSocket API编写了一个简单的文件下载程序。 下面是将文件作为二进制消息发送到客户端的方法。

    @OnMessage
    public void onMessage(Session session, String path) {
        ReadableByteChannel channel = null;
        int capacity = 1024 * 100;
        ByteBuffer buffer = ByteBuffer.allocate(capacity);
        try {
            channel = Channels.newChannel(new FileInputStream(path));
            while(channel.read(buffer) != -1){
                buffer.flip();
                session.getBasicRemote().sendBinary(buffer);
                buffer.clear();
            }
        } catch (IOException e) {
            logger.error("Error while reading the file to download", e);
        } finally {
            if (channel != null) {
                try {
                    channel.close();
                } catch (IOException e) {
                    logger.error("Error while closing the stream", e);
                }
            }
        }    
        session.getAsyncRemote().sendText("done");
    }

我已经使用SCP,基于Servlet的实现和Websocket实现计算了5GB文件的总下载时间。使用WebSocket进行文件下载要慢得多。对于5GB文件,SCP和servlet在我的测试机上花费约50秒,WebSocket需要大约180秒。

任何人都可以帮我理解我的实施有什么问题吗?

WebSockets对这种用例不好吗?任何tomcat配置参数调整都能达到更好的性能?

1 个答案:

答案 0 :(得分:0)

在tomcat中发送二进制数据有一个最大有效负载大小,即tomcat doc中引用的org.apache.tomcat.websocket.binaryBufferSize。它的默认值为8192。因此capacity必须小于或等于此值。

因此您的代码必须修改为类似的内容

int capacity = session.getMaxBinaryMessageBufferSize();

现在,将org.apache.tomcat.websocket.binaryBufferSize的大小增加到合理的更高值,这可能会增加数据传输速度,从而增加下载速度。

您可以使用web.xml中的上下文初始化参数来更改此值。

例如:

<context-param>
    <param-name>org.apache.tomcat.websocket.binaryBufferSize</param-name>
    <param-value>16384</param-value>
</context-param>