一、单文件上传实例
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();" />∅ <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(); } //绑定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_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
时间: 2024-10-22 00:25:05