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

  • 相关阅读:
    jquery easy ui 学习 (8)basic treegrid
    jquery easy ui 学习 (7) TreeGrid Actions
    jquery easy ui 学习 (6) basic validatebox
    jquery easy ui 学习 (5) windowlayout
    jquery easy ui 学习 (4) window 打开之后 限制操纵后面元素属性
    提示“应用程序无法启动,因为应用程序的并行配置不正确”不能加载 System.Data.SQLite.dll
    visual studio 添加虚线的快捷键
    VS2010打开项目时,出现“已经在解决方案中打开了具有该名称的项目”问题的解决方案
    visual studio 编译时 出现 Files 的值 乱码
    微信 连接被意外关闭
  • 原文地址:https://www.cnblogs.com/tianma3798/p/5852527.html
Copyright © 2011-2022 走看看