webentwicklung-frage-antwort-db.com.de

Dateiupload über Java Websocket API und Javascript

Ich studiere Websocket und habe ein Chat-Programm mit Websocket/Json durchgeführt. Aber ich stecke beim Hochladen von Geldautomaten fest. Jeder Rat und jede Antwort wäre dankbar.

Serverseite:

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

    }
}

Klient:

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

die Meldung "Server Side Closed Reason" lautet wie folgt

Socket geschlossen: Die dekodierte Textnachricht war zu groß für den Ausgabepuffer und der Endpunkt unterstützt keine Teilnachrichten

F1: Es scheint, dass es eine Textverarbeitungsmethode anstelle einer binären Verarbeitungsmethode gemäß dem geschlossenen Grund findet. Wie kann ich das beheben?

F2: Soll ich den Datentyp in Blob ändern, um die Datei auf der Javascript-Seite zu übertragen? Wie dann?

extra F: Darf jemand Beispielquellen für die Übertragung von Websocket-Dateien verlinken (Java-Websocket oder Javascript entweder/beides)?

Danke fürs Lesen :)

10
parn

Nach einigen Recherchen und Versuchen fand ich heraus, dass 'reader.readAsBinaryString (file);' war ein Grund für Frage 1. Ändern Sie es in "reader.readAsArrayBuffer (file);" mein erstes problem ist gelöst.

Da Websocket eine Datei automatisch als mehrere Teildaten überträgt, habe ich außerdem die Quelle wie folgt geändert. Das funktioniert! nur wenn die Dateigröße nicht so groß ist. :/

Geänderte serverseitige Quelle:

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

    }
}

Browser (Client) Seite:

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

Ich kann immer noch nicht herausfinden, wie ich eine größere Datei übertragen soll . (Ich vermute Auto-Timeout und/oder Puffergröße). Irgendwelche Ratschläge bitte?

3
parn

In meinem Fall funktioniert es, große Dateien hochzuladen, ohne dass der Browser abstürzt oder der Socket schließt.

Bitte befolgen Sie die folgenden Schritte, um es zu bearbeiten.

  1. Verwenden Sie Web-Worker, um die großen Dateien aufzuteilen
  2. senden Sie die Chunks über Websocket vom Haupt-Thread an den Server
  3. erstellen Sie eine Datei auf dem Server basierend auf Blob- oder Chunk-Informationen.
  4. behalten Sie die eindeutige ID für jede Datei bei, während Sie Dateien auf den Server hochladen, damit der Server erkennen kann, an welche Datei etwas angehängt wurde
  5. Auf der Serverseite legen Sie es nach Abschluss zunächst in einen temporären Ordner mit einer eindeutigen ID. Verschieben Sie es in den genauen Ordner.

Sie können diesen Artikel durchgehen, um sich einen Eindruck über den gesamten Arbeitsablauf zu verschaffen, der mit Websocket funktioniert.

0
Konga Raju