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

冷不防 2024-02-18 21:24 116阅读 0赞

一、单文件上传实例

HTML:

复制代码

  1. <div class="container">
  2. <div class="panel panel-default">
  3. <div class="panel-heading">分段读取文件:</div>
  4. <div class="panel-body">
  5. <input type="file" id="file" /><br />
  6. <input type="button" value="中止" onclick="stop();" />
  7. <input type="button" value="继续" onclick="containue();" />
  8. <progress id="progressOne" style="width:400px;" max="100" value="0"></progress>
  9. <blockquote id="Status" style="word-break:break-all;"></blockquote>
  10. </div>
  11. </div>
  12. </div>

复制代码

JS:

复制代码

  1. /*
  2. * 测试WebSocket上传
  3. * 本地浏览器上传速度测试单个文件,上传速度IE>FF>Google(Google浏览器慢相当多)
  4. */
  5. var fileBox = document.getElementById('file');
  6. var reader = null; //读取操作对象
  7. var step = 1024 * 256; //每次读取文件大小 ,字节数
  8. var cuLoaded = 0; //当前已经读取总数
  9. var file = null; //当前读取的文件对象
  10. var enableRead = true;//标识是否可以读取文件
  11. var total = 0; //记录当前文件总字节数
  12. var startTime = null; //标识开始上传时间
  13. fileBox.onchange = function () {
  14. //获取文件对象
  15. file = this.files[0];
  16. total = file.size;
  17. console.info("文件大小:" + file.size);
  18. if (ws == null) {
  19. if (window.confirm('建立与服务器链接失败,确定重试链接吗')) {
  20. createSocket(function () {
  21. bindReader();
  22. });
  23. }
  24. return;
  25. }
  26. bindReader();
  27. }
  28. //绑定reader
  29. function bindReader() {
  30. cuLoaded = 0;
  31. startTime = new Date();
  32. enableRead = true;
  33. reader = new FileReader();
  34. //读取一段成功
  35. reader.onload = function (e) {
  36. console.info('读取总数:' + e.loaded);
  37. if (enableRead == false)
  38. return false;
  39. //根据当前缓冲区来控制客户端读取速度
  40. if (ws.bufferedAmount > step * 10) {
  41. setTimeout(function () {
  42. //继续读取
  43. console.log('--------------》进入等待');
  44. loadSuccess(e.loaded);
  45. }, 3);
  46. } else {
  47. //继续读取
  48. loadSuccess(e.loaded);
  49. }
  50. }
  51. //开始读取
  52. readBlob();
  53. }
  54. //读取文件成功处理
  55. function loadSuccess(loaded) {
  56. //将分段数据上传到服务器
  57. var blob = reader.result;
  58. //使用WebSocket 服务器发送数据
  59. if (cuLoaded == 0) //发送文件名
  60. ws.send(file.name);
  61. ws.send(blob);
  62. //如果没有读完,继续
  63. cuLoaded += loaded;
  64. if (cuLoaded < total) {
  65. readBlob();
  66. } else {
  67. console.log('总共上传:' + cuLoaded + ',总共用时:' + (new Date().getTime() - startTime.getTime()) / 1000);
  68. }
  69. //显示结果进度
  70. var percent = (cuLoaded / total) * 100;
  71. document.getElementById('Status').innerText = percent;
  72. document.getElementById('progressOne').value = percent;
  73. }
  74. //指定开始位置,分块读取文件
  75. function readBlob() {
  76. //指定开始位置和结束位置读取文件
  77. var blob = file.slice(cuLoaded, cuLoaded + step);
  78. reader.readAsArrayBuffer(blob);
  79. }
  80. //中止
  81. function stop() {
  82. //中止读取操作
  83. console.info('中止,cuLoaded:' + cuLoaded);
  84. enableRead = false;
  85. reader.abort();
  86. }
  87. //继续
  88. function containue() {
  89. console.info('继续,cuLoaded:' + cuLoaded);
  90. enableRead = true;
  91. readBlob();
  92. }
  93. var ws = null;
  94. //创建和服务器的WebSocket 链接
  95. function createSocket(onSuccess) {
  96. var url = 'ws://localhost:55373/ashx/upload3.ashx';
  97. ws = new WebSocket(url);
  98. ws.onopen = function () {
  99. console.log('connected成功');
  100. if (onSuccess)
  101. onSuccess();
  102. }
  103. ws.onmessage = function (e) {
  104. var data = e.data;
  105. if (isNaN(data) == false) {
  106. //console.log('当前上传成功:' + data);
  107. } else {
  108. console.info(data);
  109. }
  110. }
  111. ws.onclose = function (e) {
  112. //中止客户端读取
  113. stop();
  114. console.log('链接断开');
  115. }
  116. ws.onerror = function (e) {
  117. //中止客户端读取
  118. stop();
  119. console.info(e);
  120. console.log('传输中发生异常');
  121. }
  122. }
  123. //页面加载完建立链接
  124. createSocket();

复制代码

  1. 服务器后台处理:

复制代码

  1. public void ProcessRequest(HttpContext context)
  2. {
  3. //处理WebSocket 请求
  4. context.AcceptWebSocketRequest(DoWork);
  5. }
  6. /// <summary>
  7. /// 委托处理函数定义
  8. /// </summary>
  9. /// <param name="context">当前WebSocket上下文</param>
  10. /// <returns></returns>
  11. public async Task DoWork(AspNetWebSocketContext context)
  12. {
  13. //1.获取当前WebSocket 对象
  14. WebSocket socket = context.WebSocket;
  15. string filename = "";
  16. //2.监视相应
  17. while (true)
  18. {
  19. /*
  20. * 此处缓存数组指定读取客户端数据的长度
  21. * 如果客户端发送数据超过当前缓存区,则会读取多次
  22. */
  23. ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[1024 * 256]);
  24. //接收客户端信息
  25. CancellationToken token;
  26. WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, token);
  27. if (socket.State == WebSocketState.Open)
  28. {
  29. //判断是否已经到了最后
  30. int curLength = Math.Min(buffer.Array.Length, result.Count);
  31. //判断用户传入的类型进行处理
  32. if (result.MessageType == WebSocketMessageType.Text)
  33. {
  34. string msg = Encoding.UTF8.GetString(buffer.Array, 0, curLength);
  35. filename = msg;
  36. buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes("接收文件名成功:" + filename));
  37. await socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
  38. }
  39. else if (result.MessageType == WebSocketMessageType.Binary)
  40. {
  41. //创建并保存文件,如果上传成功,返回当前接收到的文件大小
  42. string msg = SaveFile(filename, buffer, curLength);
  43. buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(curLength.ToString()));
  44. await socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
  45. }
  46. }
  47. else { break; }
  48. }
  49. }
  50. /// <summary>
  51. /// 追加二进制数据到文件
  52. /// </summary>
  53. public string SaveFile(string file, ArraySegment<byte> buffer, int Length)
  54. {
  55. //去除文件名中的前后空格
  56. file = file.Trim();
  57. string fullname = @"F:\JavaScript_Solution\H5Solition\UploadWebForm\content\" + file;
  58. try
  59. {
  60. FileStream fs = new FileStream(fullname, FileMode.Append, FileAccess.Write);
  61. try
  62. {
  63. byte[] result = buffer.ToArray();
  64. fs.Write(result, 0, Length);
  65. }
  66. finally
  67. {
  68. fs.Close();
  69. }
  70. return "保存文件成功";
  71. }
  72. catch (Exception ex)
  73. {
  74. return ex.Message;
  75. }
  76. }

复制代码

发表评论

表情:
评论列表 (有 0 条评论,116人围观)

还没有评论,来说两句吧...

相关阅读