使用Html5的WebSocket在浏览器上传文件

来源:互联网 发布:linux切换shell 编辑:程序博客网 时间:2024/06/11 07:18
使用Html5的WebSocket在浏览器上传文件

文件上传的步骤: 打开websocket--连接websocket服务器--在浏览器里选择文件--将文件读入到内存中(以arraybuffer的形式)--在socket里发送文件--完毕!

 

服务器端:

先配置好websocket的服务器, 这里用一个java的开源websocket服务器: Java-WebSocket  

根据该项目的快速教程可以建立一个websocket服务器, 就是里面的一个ChatServer.java文件. 一个聊天室服务器.

 

客户端(html):

1.建立连接

复制代码
ws = new WebSocket($("#uri").val());    //连接成功建立后响应        ws.onopen = function() {        }    //收到服务器消息后响应        ws.onmessage = function(e) {        }        //连接关闭后响应        ws.onclose = function() {            ws = null;        }
复制代码

2.读取并发送文件

复制代码
var inputElement = document.getElementById("file");var file = inputElement.files;var reader = new FileReader();//以二进制形式读取文件reader.readAsArrayBuffer(file);//文件读取完毕后该函数响应reader.onload = function loaded(evt) {        var binaryString = evt.target.result;                //发送文件        ws.send(binaryString);}
复制代码

3. 服务端响应:

public void onMessage(WebSocket conn, byte[] message) {        //saveFileFromBytes        System.out.println("收到2进制流");}

在服务端响应并保存文件, 文件传送完毕!

未完善的地方:

1. 多个文件读取, file标签中加入"multiple"属性可以选择多个文件.

2. FileRead是将文件读入到内存的, 文件太大的话需要分段读取.

要注意的地方: 

1. 读取文件时要用使用"readAsArrayBuffer"方法, 更多FileRead的用法参见 w3c的file API

2. 如果是用Chrome的话,必须把网页放在服务器上或插件里,file协议下会失败。FileRead的onload函数不会响应!

参考资料:

w3c的file API

用JavaScript读取和保存文件

FileReader详解与实例---读取并显示图像文件


完整代码:

websocket.html(有用到Jquery):

复制代码
<!DOCTYPE html><html><head><title>WebSocket Chat Client</title><meta charset="utf-8" /><script type="text/javascript" src="jquery-1.6.4.min.js"></script><script type="text/javascript" >    //判读浏览器是否支持websocket    $().ready(function() {        if ( !window.WebSocket ) {             alert("童鞋, 你的浏览器不支持该功能啊");        }             });        //在消息框中打印内容function log(text) {        $("#log").append(text+"\n");    }        //全局的websocket变量var ws;        //创建连接    $(function() {    $("#uriForm").submit(function() {        log("准备连接到" + $("#uri").val());                ws = new WebSocket($("#uri").val());        //连接成功建立后响应        ws.onopen = function() {            log("成功连接到" + $("#uri").val());        }        //收到服务器消息后响应        ws.onmessage = function(e) {            log("收到服务器消息:" + e.data + "'\n");        }        //连接关闭后响应        ws.onclose = function() {            log("关闭连接");            $("#disconnect").attr({"disabled":"disabled"});            $("#uri").removeAttr("disabled");            $("#connect").removeAttr("disabled");            ws = null;        }        $("#uri").attr({"disabled":"disabled"});        $("#connect").attr({"disabled":"disabled"});        $("#disconnect").removeAttr("disabled");        return false;    });    });        //发送字符串消息    $(function() {    $("#sendForm").submit(function() {         if (ws) {             var textField = $("#textField");             ws.send(textField.val());             log("我说:" + textField.val());             textField.val("");             textField.focus();         }         return false;    });    });        //发送arraybuffer(二进制文件)    $(function() {    $("#sendFileForm").submit(function() {        var inputElement = document.getElementById("file");        var fileList = inputElement.files;                for ( var i = 0; i < fileList.length; i++) {            console.log(fileList[i]);            log(fileList[i].name);            //发送文件名            ws.send(fileList[i].name);//            reader.readAsBinaryString(fileList[i]);//读取文件  
       var reader = new FileReader();
            reader.readAsArrayBuffer(fileList[i]);//            reader.readAsText(fileList[i]);//文件读取完毕后该函数响应            reader.onload = function loaded(evt) {                var binaryString = evt.target.result;                // Handle UTF-16 file dump                log("\n开始发送文件");                ws.send(binaryString);            }        }        return false;    });    });        $(function() {    $("#disconnect").click(function() {         if (ws) {             $("#log").empty();             ws.close();             ws = null;         }         return false;    });    });        $(function() {    $("#reset").click(function() {        $("#log").empty();         return false;    });    });        </script></head><body>    <form id="uriForm">        <input type="text" id="uri" value="ws://localhost:8887"            style="width: 200px;"> <input type="submit" id="connect"            value="Connect"><input type="button" id="disconnect"            value="Disconnect" disabled="disabled">    </form>    <br>        <form id="sendFileForm">        <input id="file" type="file" multiple />        <input type="submit" value="Send" />        <input type="button" id="reset" value="清空消息框"/>    </form>    <br>    <form id="sendForm">        <input type="text" id="textField" value="" style="width: 200px;">        <input type="submit" value="Send">    </form>    <br>    <form>        <textarea id="log" rows="30" cols="100"            style="font-family: monospace; color: red;"></textarea>    </form>    <br></body></html>
复制代码


ChatServer.java(需要导入WebSocket.jar):

复制代码
package jyu.webserver;import java.io.BufferedOutputStream;import java.io.BufferedReader;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStreamReader;import java.net.InetAddress;import java.net.InetSocketAddress;import java.net.UnknownHostException;import org.java_websocket.WebSocket;import org.java_websocket.WebSocketServer;import org.java_websocket.handshake.ClientHandshake;/** * A simple WebSocketServer implementation. Keeps track of a "chatroom". */public class ChatServer extends WebSocketServer {    private String fileName = null;    public ChatServer( int port ) throws UnknownHostException {        super( new InetSocketAddress( InetAddress.getByName( "localhost" ), port ) );    }        public ChatServer( InetSocketAddress address ) {        super( address );    }    public ChatServer( String address ,int port) throws UnknownHostException {        super( new InetSocketAddress( InetAddress.getByName( address ), port ) );    }    @Override    public void onOpen( WebSocket conn, ClientHandshake handshake ) {        try {            this.sendToAll( conn + " entered the room!" );        } catch ( InterruptedException ex ) {            ex.printStackTrace();        }        System.out.println( conn + " entered the room!" );    }    @Override    public void onClose( WebSocket conn, int code, String reason, boolean remote ) {        try {            this.sendToAll( conn + " has left the room!" );        } catch ( InterruptedException ex ) {            ex.printStackTrace();        }        System.out.println( conn + " has left the room!" );    }    @Override    public void onMessage( WebSocket conn, String message ) {        conn.getRemoteSocketAddress().getAddress().getAddress();        try {            this.sendToAll( conn + "说: " + message );        } catch ( InterruptedException ex ) {            ex.printStackTrace();        }//        System.out.println( conn + ": " + message );//        byte[] fileBanary = message.getBytes();//        saveFileFromBytes(fileBanary, "src/test.png");        fileName = message;        System.out.println("收到字符串流");    }        @Override    public void onMessage(WebSocket conn, byte[] message) {        saveFileFromBytes(message, "src/" + fileName);        System.out.println("收到2进制流");    }    public static void main( String[] args ) throws InterruptedException , IOException {        WebSocket.DEBUG = false;        int port = 8887;        try {            port = Integer.parseInt( args[ 0 ] );        } catch ( Exception ex ) {        }        ChatServer s = new ChatServer("localhost", port );        s.start();        System.out.println( "ChatServer started on port: " + s.getPort() );        BufferedReader sysin = new BufferedReader( new InputStreamReader( System.in ) );        while ( true ) {            String in = sysin.readLine();            s.sendToAll( in );        }    }    @Override    public void onError( WebSocket conn, Exception ex ) {        ex.printStackTrace();    }    /**     * Sends <var>text</var> to all currently connected WebSocket clients.     *      * @param text     *            The String to send across the network.     * @throws InterruptedException     *             When socket related I/O errors occur.     */    public void sendToAll( String text ) throws InterruptedException {        for( WebSocket c : connections() ) {            c.send( text );        }    }        public static boolean saveFileFromBytes(byte[] b, String outputFile)        {          BufferedOutputStream stream = null;          File file = null;          try          {            file = new File(outputFile);            FileOutputStream fstream = new FileOutputStream(file);            stream = new BufferedOutputStream(fstream);            stream.write(b);          }          catch (Exception e)          {            e.printStackTrace();          return false;        }          finally          {            if (stream != null)            {              try              {                stream.close();              }              catch (IOException e1)              {                e1.printStackTrace();              }            }          }          return true;        }  }
原创粉丝点击