Websocket文件上传速度问题(Java websocket API和Javascript)

我几乎没有做过websocket文件上传function。 但上传速度似乎很慢。 我已经使用Java API for websocket Server和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(); } } 

客户:

    Chat   

File Upload

Select file

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()

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

提前致谢 :)

尝试将setMaxBinaryMessageBufferSize()置于1MB到您的会话。 不完全知道javax,但是使用jetty它不会改变碎片大小,但速度会大大增加。

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

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

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

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

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

请参阅此示例https://github.com/nickytd/websocket-message-handlers-example/blob/master/websocket.messagehandler.web/src/main/java/websocket/messagehandler/example/endpoints/FullEchoEndpoint.java

Interesting Posts