java - 与 Servlet 相比,使用 Websocket 下载文件速度较慢

标签 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 配置参数以获得更好的性能?

最佳答案

在 tomcat 中发送二进制数据有一个最大负载大小,即 org.apache.tomcat.websocket.binaryBufferSize 引用自 tomcat doc .它的默认值为 8192。所以容量必须小于等于这个值。

所以你的代码必须修改成这样

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> 

关于java - 与 Servlet 相比,使用 Websocket 下载文件速度较慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29558008/

相关文章:

ssl - 如何在 Play!Framework WebSockets ("wss://"中使用 TLS)

c++ - Boost websocket 接受挂起

spring - 如何使用 Tomcat + Spring Security 对静态内容强制执行 HTTPS

java - 一一按下按钮

java - java 中的 menu.add 不会将 NONE 作为有效整数

java - 对于大文件,将字符串值映射到整数

IntelliJ IDEA 中的 Tomcat 配置

java - 如何从 tomcat 提供静态内容

iOS 破坏了发送到服务器的 TLS 数据

Java 泛型和 Hadoop : how to get a class variable