首页 > 代码库 > HTML5 文件域+FileReader 分段读取文件并上传(七)-WebSocket

HTML5 文件域+FileReader 分段读取文件并上传(七)-WebSocket

一、单文件上传实例

HTML:

<div class="container">    <div class="panel panel-default">        <div class="panel-heading">分段读取文件:</div>        <div class="panel-body">            <input type="file" id="file" /><br />            <input type="button" value="中止" onclick="stop();" />&empty;            <input type="button" value="继续" onclick="containue();" />            <progress id="progressOne" style="width:400px;" max="100" value="0"></progress>            <blockquote id="Status" style="word-break:break-all;"></blockquote>        </div>    </div></div>

JS:

/*    * 测试WebSocket上传    * 本地浏览器上传速度测试单个文件,上传速度IE>FF>Google(Google浏览器慢相当多)    */var fileBox = document.getElementById(‘file‘);var reader = null;  //读取操作对象var step = 1024 * 256;  //每次读取文件大小 ,字节数var cuLoaded = 0; //当前已经读取总数var file = null; //当前读取的文件对象var enableRead = true;//标识是否可以读取文件var total = 0;        //记录当前文件总字节数var startTime = null; //标识开始上传时间fileBox.onchange = function () {    //获取文件对象    file = this.files[0];    total = file.size;    console.info("文件大小:" + file.size);    if (ws == null) {        if (window.confirm(‘建立与服务器链接失败,确定重试链接吗‘)) {            createSocket(function () {                bindReader();            });        }        return;    }    bindReader();}//绑定readerfunction bindReader() {    cuLoaded = 0;    startTime = new Date();    enableRead = true;    reader = new FileReader();    //读取一段成功    reader.onload = function (e) {        console.info(‘读取总数:‘ + e.loaded);        if (enableRead == false)            return false;        //根据当前缓冲区来控制客户端读取速度        if (ws.bufferedAmount > step * 10) {            setTimeout(function () {                //继续读取                console.log(‘--------------》进入等待‘);                loadSuccess(e.loaded);            }, 3);        } else {            //继续读取            loadSuccess(e.loaded);        }    }    //开始读取    readBlob();}//读取文件成功处理function loadSuccess(loaded) {    //将分段数据上传到服务器    var blob = reader.result;    //使用WebSocket 服务器发送数据    if (cuLoaded == 0) //发送文件名        ws.send(file.name);    ws.send(blob);    //如果没有读完,继续    cuLoaded += loaded;    if (cuLoaded < total) {        readBlob();    } else {        console.log(‘总共上传:‘ + cuLoaded + ‘,总共用时:‘ + (new Date().getTime() - startTime.getTime()) / 1000);    }    //显示结果进度    var percent = (cuLoaded / total) * 100;    document.getElementById(‘Status‘).innerText = percent;    document.getElementById(‘progressOne‘).value =http://www.mamicode.com/ percent;}//指定开始位置,分块读取文件function readBlob() {    //指定开始位置和结束位置读取文件    var blob = file.slice(cuLoaded, cuLoaded + step);    reader.readAsArrayBuffer(blob);}//中止function stop() {    //中止读取操作    console.info(‘中止,cuLoaded:‘ + cuLoaded);    enableRead = false;    reader.abort();}//继续function containue() {    console.info(‘继续,cuLoaded:‘ + cuLoaded);    enableRead = true;    readBlob();}var ws = null;//创建和服务器的WebSocket 链接function createSocket(onSuccess) {    var url = ‘ws://localhost:55373/ashx/upload3.ashx‘;    ws = new WebSocket(url);    ws.onopen = function () {        console.log(‘connected成功‘);        if (onSuccess)            onSuccess();    }    ws.onmessage = function (e) {        var data =http://www.mamicode.com/ e.data;        if (isNaN(data) == false) {            //console.log(‘当前上传成功:‘ + data);        } else {            console.info(data);        }    }    ws.onclose = function (e) {        //中止客户端读取        stop();        console.log(‘链接断开‘);    }    ws.onerror = function (e) {        //中止客户端读取        stop();        console.info(e);        console.log(‘传输中发生异常‘);    }}//页面加载完建立链接createSocket();
服务器后台处理:
    public void ProcessRequest(HttpContext context)    {        //处理WebSocket 请求        context.AcceptWebSocketRequest(DoWork);    }    /// <summary>    /// 委托处理函数定义    /// </summary>    /// <param name="context">当前WebSocket上下文</param>    /// <returns></returns>    public async Task DoWork(AspNetWebSocketContext context)    {        //1.获取当前WebSocket 对象        WebSocket socket = context.WebSocket;        string filename = "";        //2.监视相应        while (true)        {            /*                * 此处缓存数组指定读取客户端数据的长度                * 如果客户端发送数据超过当前缓存区,则会读取多次                */            ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[1024 * 256]);            //接收客户端信息            CancellationToken token;            WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, token);            if (socket.State == WebSocketState.Open)            {                //判断是否已经到了最后                int curLength = Math.Min(buffer.Array.Length, result.Count);                //判断用户传入的类型进行处理                if (result.MessageType == WebSocketMessageType.Text)                {                    string msg = Encoding.UTF8.GetString(buffer.Array, 0, curLength);                    filename = msg;                    buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes("接收文件名成功:" + filename));                    await socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);                }                else if (result.MessageType == WebSocketMessageType.Binary)                {                    //创建并保存文件,如果上传成功,返回当前接收到的文件大小                    string msg = SaveFile(filename, buffer, curLength);                    buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(curLength.ToString()));                    await socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);                }            }            else { break; }        }    }    /// <summary>    /// 追加二进制数据到文件    /// </summary>    public string SaveFile(string file, ArraySegment<byte> buffer, int Length)    {        //去除文件名中的前后空格        file = file.Trim();        string fullname = @"F:\JavaScript_Solution\H5Solition\UploadWebForm\content\" + file;        try        {            FileStream fs = new FileStream(fullname, FileMode.Append, FileAccess.Write);            try            {                byte[] result = buffer.ToArray();                fs.Write(result, 0, Length);            }            finally            {                fs.Close();            }            return "保存文件成功";        }        catch (Exception ex)        {            return ex.Message;        }    }

 


本地浏览器上传速度测试单个文件,上传速度IE>FF>Google(Google浏览器慢相当多)
原因:每次send发送数据的时候Google浏览器发送的数据量相对较小

技术分享技术分享技术分享

分段上传文件(六):http://www.cnblogs.com/tianma3798/p/5845291.html
分段读取文件(五):http://www.cnblogs.com/tianma3798/p/5841584.html

分段读取文件(四):http://www.cnblogs.com/tianma3798/p/5839869.html

 读取文件三:http://www.cnblogs.com/tianma3798/p/5839810.html

读取文件二:http://www.cnblogs.com/tianma3798/p/5839791.html

读取文件一:http://www.cnblogs.com/tianma3798/p/4355949.html

HTML5 文件域+FileReader 分段读取文件并上传(七)-WebSocket