使用java websocket API和Javascript上传文件

我正在研究websocket并且已经使用websocket / json完成了聊天程序。 但我坚持上传ATM的文件。 任何建议和答案都会感激不尽。

服务器端:

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 { @OnOpen public void open(Session session, EndpointConfig conf) { System.out.println("chat ws server open"); } @OnMessage public void processUpload(ByteBuffer msg, boolean last, Session session) { System.out.println("Binary message"); FileOutputStream fos = null; File file = new File("D:/download/tmp.txt"); try { fos = new FileOutputStream(file); } catch (FileNotFoundException e) { e.printStackTrace(); } byte readdata = (byte) -999; while(readdata!=-1) { readdata=msg.get(); try { fos.write(readdata); } catch (IOException e) { e.printStackTrace(); } } } @OnMessage public void message(Session session, String msg) { System.out.println("got msg: " + msg + msg.length()); } @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]; var reader = new FileReader(); var rawData = new ArrayBuffer(); reader.loadend = function() { } reader.onload = function(e) { rawData = e.target.result; ws.send(rawData); alert("the File has been transferred.") } reader.readAsBinaryString(file); }

服务器端关闭原因消息如下

套接字关闭:解码的文本消息对于输出缓冲区而言太大,并且端点不支持部分消息

Q1:似乎是根据封闭原因找到文本处理方法而不是二进制处理方法,我该如何解决这个问题呢?

Q2:我应该将数据类型更改为Blob以在javascript端传输文件吗? 那怎么样?

额外的问:可以有人链接websocket文件传输的示例源(java websocket或javascript或两者)?

谢谢阅读 :)

经过一番研究和尝试,我发现’reader.readAsBinaryString(file);’ 是问题1的原因。将其更改为’reader.readAsArrayBuffer(file);’ 我的第一个问题已经解决了。

另外,由于websocket自动将文件作为多个部分数据传输,因此我更改了源代码如下。 这有效! 只有当文件大小不那么大时。 :/

更改了服务器端源:

 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/"; @OnOpen public void open(Session session, EndpointConfig conf) { System.out.println("chat ws server open"); } @OnMessage public void processUpload(ByteBuffer msg, boolean last, Session session) { System.out.println("Binary Data"); 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

我仍然无法弄清楚如何传输更大尺寸的文件 。 (我怀疑自动超时和/或缓冲区大小)。 有什么建议吗?

在我的情况下,它工作上传大文件没有任何浏览器崩溃或套接字关闭。

请按照以下步骤进行操作。

  1. 使用Web worker切片大文件
  2. 使用主线程中的Websocket将块发送到服务器
  3. 根据blob或chunk信息在服务器端构造文件。
  4. 在将文件上载到服务器时为每个文件维护唯一ID,以便服务器可以识别附加到哪个文件
  5. 在服务器端最初将它放在具有唯一ID的临时文件夹中,在完成后将其移动到确切的文件夹。

您可以通过本文了解完整的工作流程,以及它与Websocket的协作。