Websocket文件上传速度问题(Java websocket API和Javascript) [英] Websocket File upload speed issue (Java websocket API and Javascript)

查看:173
本文介绍了Websocket文件上传速度问题(Java websocket API和Javascript)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我几乎没有做过websocket文件上传功能。但上传速度似乎很慢。我使用了Java API for websocket Server和javascript for client。

I barely made websocket file upload function. But uploading speed seems to be slow. I have used Java API for websocket Server and javascript for client.

服务器:

package websocket;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;

import javax.websocket.CloseReason;
import javax.websocket.EndpointConfig;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

@ServerEndpoint("/receive/fileserver")
public class FileServer {
    static File uploadedFile = null;
    static String fileName = null;
    static FileOutputStream fos = null;
    final static String filePath="d:/download/";
    int fCount=0;

    @OnOpen
    public void open(Session session, EndpointConfig conf) {
        System.out.println("Websocket server open");
    }

    @OnMessage
    public void processUpload(ByteBuffer msg, boolean last, Session session) {
        System.out.println("Binary Data: " + fCount + ", Capacity: "+ msg.capacity());      
        fCount++;
        while(msg.hasRemaining()) {         
            try {
                fos.write(msg.get());
            } catch (IOException e) {               
                e.printStackTrace();
            }
        }       
    }

    @OnMessage
    public void message(Session session, String msg) {
        System.out.println("got msg: " + msg);
        if(!msg.equals("end")) {
            fileName=msg.substring(msg.indexOf(':')+1);
            uploadedFile = new File(filePath+fileName);
            try {
                fos = new FileOutputStream(uploadedFile);
            } catch (FileNotFoundException e) {     
                e.printStackTrace();
            }
        }else {
            try {
                fos.flush();
                fos.close();                
            } catch (IOException e) {       
                e.printStackTrace();
            }
        }
    }

    @OnClose
    public void close(Session session, CloseReason reason) {
        System.out.println("socket closed: "+ reason.getReasonPhrase());
    }

    @OnError
    public void error(Session session, Throwable t) {
        t.printStackTrace();

    }
}

客户:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Chat</title>
</head>
<body>
    <h2>File Upload</h2>
    Select file
    <input type="file" id="filename" />
    <br>
    <input type="button" value="Connect" onclick="connectChatServer()" />
    <br>
    <input type="button" value="Upload" onclick="sendFile()" />
    <script>
        var ws;

        function connectChatServer() {
            ws = new WebSocket(
                    "ws://localhost:8080/MyHomePage/receive/fileserver");

            ws.binaryType = "arraybuffer";
            ws.onopen = function() {
                alert("Connected.")
            };

            ws.onmessage = function(evt) {
                alert(evt.msg);
            };

            ws.onclose = function() {
                alert("Connection is closed...");
            };
            ws.onerror = function(e) {
                alert(e.msg);
            }

        }


        function sendFile() {
            var file = document.getElementById('filename').files[0];
            ws.send('filename:'+file.name);
            var reader = new FileReader();
            var rawData = new ArrayBuffer();            

            var fStart = 0; //start byte
            var fEnd = 1024*1024; //packet size & end byte when slicing file.
            var fileFrag; //file fragment                       

            reader.loadend = function() {           
                console.log('load end');
            }

            reader.onload = function(e) {
                if(e.target.readyState == FileReader.DONE) {
                    rawData = e.target.result;              
                    //var blob = new Blob([rawData]);           
                    ws.send(rawData);   
                }               
            }

            fileFrag = file.slice(fStart, fEnd);
            reader.readAsArrayBuffer(fileFrag);         

            objRun = setInterval(function() {               
                if (ws.bufferedAmount == 0) {                   
                    if(reader.readyState == FileReader.DONE) {                      
                        if(fStart<file.size) {                          
                            fStart = fEnd + 1;
                            fEnd = fStart + 1024*1024;
                            fileFrag = file.slice(fStart, fEnd);
                            console.log('fileFrag Size: ' + fileFrag.size + 'Frag End: ' + fEnd);
                            reader.readAsArrayBuffer(fileFrag); 
                        } else clearInterval(objRun);
                    } //end of readyState
                } //end of ws.buffer
            }, 5);//end of setInterval      
        }//end of sendFile()    

    </script>
</body>
</html>

根据服务器端日志,碎片数据大小为8K。我怎么能增加这个?或者有什么方法可以提高上传速度吗?

According to server side log, fragmented data size is 8K. How can I increase this? or is there any way to improve uploading speed?

提前致谢:)

推荐答案

会话对象有很多方法。其中一些是为了解决你的问题而引入的。

The session object has many methods. Some of them are introduced to deal with your problem.

setMaxBinaryMessageBufferSize(int lenght) - 因为你的客户端似乎一次发送整个文件数据,缓冲区就在服务器无法处理该大小。

setMaxBinaryMessageBufferSize(int lenght) - because it seems that your client sends the entire file data at once, the the buffer on the server is unable to handle that size.

实际上,发送整个文件数据会使程序易受攻击并依赖于它处理的文件。这也不是一个好的表现决定。因为你提到你的过程很慢。我一般来说,分配足够大的缓冲区大小以便能够将文件数据保存在内存中会降低性能,因为它可能会导致内存交换。

In reality, sending the whole file data makes the program vulnerable and dependent on the file it processes. It is also not a good performance decision. Because you mention that your process works quite slow. I general, allocating the buffer size large enough to be able to hold the file data in memory could degrade performance because it could cause memory swapping.

我会上传大文件多个细分。我使用一些套接字API(而不是WebSocket API)来做到这一点,它的工作速度非常快。

I would upload large files by multiple segments. I did this using some socket APIs (not WebSocket API) and it work quite fast.

另一点。我注意到您对不同的消息类型使用两种OnMessage方法。但是,我认为你需要在那种情况下使用MessageHandlers,否则你报告的程序会混淆哪个消息去哪个方法。

Another point. I noticed that you are using two OnMessage methods for different message types. However, I think you need to use in that case MessageHandlers, otherwise your program, as you reported, can confuse which message go to which method.

请看这个例子
https://github.com/nickytd/websocket-message-handlers-example/blob/master/websocket.messagehandler.web/src/main/java/websocket/messagehandler/example/ endpoints / FullEchoEndpoint.java

这篇关于Websocket文件上传速度问题(Java websocket API和Javascript)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆