【问题标题】:File upload using java websocket API and Javascript使用 java websocket API 和 Javascript 上传文件
【发布时间】:2014-03-13 05:31:45
【问题描述】:

我正在学习 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();

    }
}

客户:

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

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

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

Q1:根据关闭的原因,似乎是寻找文本处理方式而不是二进制处理方式,请问如何解决?

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

额外问:任何人都可以链接 websocket 文件传输的示例源(java websocket 或 javascript 之一/两者)吗?

感谢阅读:)

【问题讨论】:

  • 我知道如何上传文件,但现在卡在上传速度上。如果你有兴趣,你可以找到源和新问题here

标签: java javascript websocket blob


【解决方案1】:

经过一些研究和尝试,我发现'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();

    }
}

浏览器(客户端)端:

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

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

【讨论】:

    【解决方案2】:

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

    请按照以下步骤操作。

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

    您可以通过article 了解完整的工作流程,它与 Websocket 的配合。

    【讨论】:

      猜你喜欢
      • 2014-03-17
      • 2012-06-20
      • 2013-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多