zoukankan      html  css  js  c++  java
  • 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="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();
    }
    //绑定reader
    function 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 = 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 = 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_SolutionH5SolitionUploadWebFormcontent" + 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浏览器发送的数据量相对较小

    
    
  • 相关阅读:
    BZOJ3518 : 点组计数
    BZOJ2217 : [Poi2011]Lollipop
    李洪强经典面试题40-可能碰到的iOS笔试面试题-C语言
    对AFN的二次封装
    李洪强经典面试题39-iOS 程序员 6 级考试(答案和解释)
    iOS五种本地缓存数据方式
    iOS开发网络篇—数据缓存
    iOS中的通知
    李洪强漫谈iOS开发[C语言-048]-打印平方表
    李洪强漫谈iOS开发[C语言-047]-数列求和
  • 原文地址:https://www.cnblogs.com/tianma3798/p/5852475.html
Copyright © 2011-2022 走看看