2014-02-14 72 views
8

我正在學習websocket並使用websocket/json完成了聊天程序。但我被卡在文件上傳自動取款機。任何建議&答案會很感激。使用java websocket API和Javascript進行文件上傳

服務器端:

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

    } 
} 

客戶:

<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
<title>Chat</title> 
<script type="text/javascript" src="/MyHomePage/jquery-2.0.3.min.js"></script> 
</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]; 
      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); 

     } 


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

服務器端關閉原因消息是如下

插座關閉:解碼後的短信太大輸出緩衝區和端點不支持參數tial消息

問題1:看來它是根據封閉原因找到文本處理方法而不是二進制處理方法,該如何解決?

Q2:我應該改變數據類型爲Blob在JavaScript端傳輸文件?那怎麼樣?

extra問:有誰可以鏈接websocket文件傳輸的示例源(java websocket或者javascript /兩者)?

感謝您的閱讀:)

+0

我想出瞭如何上傳文件,但現在停留在上傳速度。如果你有興趣,你可以找到源和新的問題[這裏](http://stackoverflow.com/questions/21846530/websocket-file-upload-speed-issue-java-websocket-api-and-javascript)。 – parn

回答

3

一些研究和嘗試後,我發現 'reader.readAsBinaryString(文件);'是問題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(); 

    } 
} 

瀏覽器(客戶端)側:

<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
<title>Chat</title> 
<script type="text/javascript" src="/MyHomePage/jquery-2.0.3.min.js"></script> 
</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();    
      //alert(file.name); 

      reader.loadend = function() { 

      } 
      reader.onload = function(e) { 
       rawData = e.target.result; 
       ws.send(rawData); 
       alert("the File has been transferred.") 
       ws.send('end'); 
      } 

      reader.readAsArrayBuffer(file); 

     } 


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

不過我不能找出如何傳送尺寸較大的文件。 (我懷疑自動超時和/或緩衝區大小)。任何建議plz?

0

在我的情況下,它的工作,上傳大文件沒有任何瀏覽器崩潰或套接字關閉。

請按照以下步驟進行操作。

  1. 使用網絡工作者裁大文件
  2. 從主線程發送使用WebSocket的大塊服務器
  3. 構建文件基於BLOB或塊信息服務器端。
  4. 維護每個文件的唯一ID,同時將文件上傳到服務器,使服務器可以識別哪個文件追加
  5. 在服務器端最初將其放置在臨時文件夾中有唯一的ID完成後,將其移動到文件夾準確。

您可以通過此article瞭解完整的工作流程,它與Websocket一起工作。

相關問題