您的位置:首页 > Web前端 > HTML5

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

2013-08-28 16:12 477 查看
文件上传的步骤: 打开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;  
      }  
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: