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" id="bodyOne">
                <input type="file" id="file"  multiple/><br />
            </div>
        </div>
    </div>

    JS:

    1.封装单文上传实例

    //封装 单个文件上传实例
    (function () {
        var url = 'ws://localhost:55373/ashx/upload4.ashx';
        //指定上传文件,创建上传操作对象
        function uploadOperate(file) {
            var _this = this;
            this.reader = new FileReader();//读取文件对象
            this.step = 1024 * 256;//每次读取文件字节数
            this.curLoaded = 0; //当前读取位置
            this.file = file;   //当前文件对象
            this.enableRead = true; //指定是否可读取,
            this.total = file.size;  //当前文件总大小
            this.startTime = new Date(); //开始读取时间
            //创建显示
            this.createItem();
            this.initWebSocket(function () {
                _this.bindReader();
            });
            console.info('文件大小:' + this.total);
        }
        uploadOperate.prototype = {
            //绑定读取事件
            bindReader: function () {
                var _this = this;
                var reader = this.reader;
                var ws = this.ws;
                reader.onload = function (e) {
                    //判断是否能再次读取
                    if (_this.enableRead == false) return;
                    //根据当前缓冲区 控制读取速度
                    if (ws.bufferedAmount >= _this.step * 20) {
                        setTimeout(function () {
                            _this.loadSuccess(e.loaded);
                        }, 5);
                        console.info('---->进入等待');
                    } else {
                        _this.loadSuccess(e.loaded);
                    }
                }
                //开始读取
                _this.readBlob();
            },
            //读取成功,操作处理
            loadSuccess: function (loaded) {
                var _this = this;
                var ws = _this.ws;
                //使用WebSocket 将二进制输出上传到服务器
                var blob = _this.reader.result;
                if (_this.curLoaded <= 0)
                    ws.send(_this.file.name);
                ws.send(blob);
                //当前发送完成,继续读取
                _this.curLoaded += loaded;
                if (_this.curLoaded < _this.total) {
                    _this.readBlob();
                } else {
                    //发送读取完成
                    ws.send('发送完成');
                    //读取完成
                    console.log('总共上传:' + _this.curLoaded + ',总共用时:' + (new Date().getTime() - _this.startTime.getTime()) / 1000);
                }
                //显示进度等
                _this.showProgress();
            },
            //创建显示项
            createItem: function () {
                var _this = this;
                var blockquote = document.createElement('blockquote');
                var abort = document.createElement('input');
                abort.type = 'button';
                abort.value = '中止';
                abort.onclick = function () {
                    _this.stop();
                };
                blockquote.appendChild(abort);
    
                var containue = document.createElement('input');
                containue.type = 'button';
                containue.value = '继续';
                containue.onclick = function () {
                    _this.containue();
                };
                blockquote.appendChild(containue);
    
                var progress = document.createElement('progress');
                progress.style.width = '400px';
                progress.max = 100;
                progress.value = 0;
                blockquote.appendChild(progress);
                _this.progressBox = progress;
    
                var status = document.createElement('p');
                status.id = 'Status';
                blockquote.appendChild(status);
                _this.statusBox = status;
    
                document.getElementById('bodyOne').appendChild(blockquote);
            },
            //显示进度
            showProgress: function () {
                var _this = this;
                var percent = (_this.curLoaded / _this.total) * 100;
                _this.progressBox.value = percent;
                _this.statusBox.innerHTML = percent;
            },
            //执行读取文件
            readBlob: function () {
                var blob = this.file.slice(this.curLoaded, this.curLoaded + this.step);
                this.reader.readAsArrayBuffer(blob);
            },
            //中止读取
            stop: function () {
                this.enableRead = false;
                this.reader.abort();
                console.log('读取中止,curLoaded:' + this.curLoaded);
            },
            //继续读取
            containue: function () {
                this.enableRead = true;
                this.readBlob();
                console.log('读取继续,curLoaded:' + this.curLoaded);
            },
            //初始化 绑定创建连接
            initWebSocket: function (onSuccess) {
                var _this = this;
                var ws = this.ws = new WebSocket(url); //初始化上传对象
                ws.onopen = function () {
                    console.log('connect创建成功');
                    if (onSuccess)
                        onSuccess();
                }
                ws.onmessage = function (e) {
                    var data = e.data;
                    if (isNaN(data) == false) {
                        console.info('后台接收成功:' + data);
                    } else {
                        console.info(data);
                    }
                }
                ws.onclose = function (e) {
                    //中止读取
                    _this.stop();
                    console.log('connect已经断开');
                }
                ws.onerror = function (e) {
                    //中止读取
                    _this.stop();
                    console.log('发生异常:' + e.message);
                }
            }
        };
        window.uploadOperate = uploadOperate;
    })();
    View Code

    2.绑定页面处理

    /*
    * 测试WebSocket多文件上传
    * 上传速度取决于 每次send() 的数据大小 ,Google之所以相对比较慢,是因为每次send的数据量太小
    */
    var fileBox = document.getElementById('file');
    fileBox.onchange = function () {
        var files = this.files;
        for (var i = 0; i < files.length; i++) {
            var file = files[i];
            var operate = new uploadOperate(file);
        }
    }

    服务器后台封装处理:

        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 = "";
            byte[] bufferAll = new byte[1024 * 256 * 2];//缓存接收文件
    
            //Array.Copy
            //byte[] bufferAll = new byte[];
            int loaded = 0;  //当前缓冲数量
            //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);
                    try
                    {
                        //判断用户传入的类型进行处理
                        if (result.MessageType == WebSocketMessageType.Text)
                        {
                            string msg = Encoding.UTF8.GetString(buffer.Array, 0, curLength);
                            if (msg == "发送完成")
                            {
                                //发送完成,全部写入文件
                                string str = SaveFile(filename, bufferAll, loaded);
                                loaded = 0;
                                ArraySegment<byte> echor = new ArraySegment<byte>(Encoding.UTF8.GetBytes(curLength.ToString()));
                                await socket.SendAsync(echor, WebSocketMessageType.Text, true, CancellationToken.None);
                            }
                            else
                            {
                                filename = msg;
                                msg = string.Format("服务器链接数量:{0},当前链接ID={1},接收文件名:{2}",
                                AspNetWebSocketContext.ConnectionCount, context.AnonymousID, filename);
                                ArraySegment<byte>  echor = new ArraySegment<byte>(Encoding.UTF8.GetBytes(msg));
                                await socket.SendAsync(echor, WebSocketMessageType.Text, true, CancellationToken.None);
                            }
                        }
                        else if (result.MessageType == WebSocketMessageType.Binary)
                        {
                            var temp = loaded + curLength;
                            if ((temp) > bufferAll.Length)
                            {
                                //先写入文件
                                string msg = SaveFile(filename, bufferAll, loaded);
                                //添加到缓冲区
                                Array.Copy(buffer.Array, 0, bufferAll, 0, curLength);
                                loaded = curLength;
                                //返回相应
                                ArraySegment<byte> echor = new ArraySegment<byte>(Encoding.UTF8.GetBytes(curLength.ToString()));
                                await socket.SendAsync(echor, WebSocketMessageType.Text, true, CancellationToken.None);
                            }
                            else
                            {
                                //添加到缓冲区
                                Array.Copy(buffer.Array, 0, bufferAll, loaded, curLength);
                                loaded = temp;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
    
                           
                    }
                }
                else { break; }
            }
        }
        /// <summary>
        /// 追加二进制数据到文件
        /// </summary>
        public string SaveFile(string file, 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);
                    fs.Write(buffer, 0, Length);
                }
                finally
                {
                    fs.Close();
                }
                return "保存文件成功";
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }
    View Code

    运行结果显示:

    分段上传文件(七):http://www.cnblogs.com/tianma3798/p/5852475.html

  • 相关阅读:
    查看MAC系统JRE和JDK版本
    【转】频点CTO张成:基于Cocos2d的MMORPG开发经验
    Android上常见度量单位【xdpi、hdpi、mdpi、ldpi】解读
    常见android手机分辨率(xxhdpi,xhdpi)
    Android市场官方的统计信息
    【转】腾讯分析移动设备屏幕分辨率分析报告-(数据基于2012年12月至2013年1月上半月)
    error “base class has incomplete type”
    Eclipse 各种包说明
    怎么鉴别五帝钱真假
    【jzoj 6276】树(线段树)(扫描线)
  • 原文地址:https://www.cnblogs.com/tianma3798/p/5852527.html
Copyright © 2011-2022 走看看