HTML5 breakpoint resume upload sample code sharing
BreakpointUpload, which is more reliable in java. Generally, Flex is used. I admit that I have just touched upon it and am not proficient in it. HTML 5 has a Blob object (the File object inherits it), and this object has a method slice method. A file can be fragmented. In addition, the File API and WebStorage of HTML 5 have been used.
The code is relatively complicated. After dividing a file into small pieces, Each upload will put the uploaded bytes into LocalStorage. For how to clear the cache in LocalStorage, please refer to Chrome - HTML 5 Local Storage. If the upload is paused or the browser is closed next time, The upload will start from that node.
PS: For demo operation, please establish the WS connection first, and then select file upload
Please accept the code:
<!DOCTYPE html> <html> <head> <title>使用WebSocket实现断点续传文件</title> <meta charset="utf-8"> </head> <script type="text/javascript" src="demo.js"></script> <body onload="init();"> <button onclick="webSocketConn();">创建连接</button>(step1) <div class="row"> <label for="fileToUpload">Select a File to Upload</label> <input type="file" name="fileToUpload" id="fileToUpload" onchange="fileSelected();"/>(step2) </div> <div id="fileName"></div> <div id="fileSize"></div> <div id="fileType"></div> <div class="row"> <button onclick="sendFileName();uploadFile()">上传</button>(step3) <button onclick="pauseUpload()">暂停</button> <label id="progressNumber"></label> </div> <div id="msg" style="max-height: 400px; overflow:auto;min-height: 100px;"> </div> </body> </html>
####### 断点续传 ###### author:linrb createTime: 2012-08-22 QQ: 569830404 */ var websocket = null; //websocket var msg = null; //日志 var paragraph = 10240; //每次分片传输文件的大小 10KB var blob = null;// 分片数据的载体Blob对象 var file = null; //传输的文件 var startSize,endSize = 0; //分片的始终字节点 var uploadState = 0; // 0: 无上传/取消, 1: 上传中, 2: 暂停 //初始化消息框 function init(){ msg = document.getElementById("msg"); } /** * 分片上传文件 */ function uploadFile() { if(file){ //将上传状态设置成1 uploadState = 1; endSize = getLastestUploadEndSize(file); var reader = new FileReader(); reader.onload = function loaded(evt) { var ArrayBuffer = evt.target.result; websocket.send(ArrayBuffer); uploadProgress(endSize); }; if(endSize < file.size){ //先发送文件名称 //websocket.send(file.name); //处理文件发送(字节) startSize = endSize; if(paragraph > (file.size - endSize)){ endSize = file.size; }else{ endSize += paragraph ; } if (file.webkitSlice) { //webkit浏览器 blob = file.webkitSlice(startSize, endSize); }else blob = file.slice(startSize, endSize); reader.readAsArrayBuffer(blob); } } } //显示处理进程 function uploadProgress(uploadLen) { var percentComplete = Math.round(uploadLen * 100 / file.size); document.getElementById('progressNumber').innerHTML = percentComplete.toString() + '%'; //保存到LocalStorage一边下次传输,可以记忆起这个断点 localStorage.setItem(file.lastModifiedDate + "_" + file.name, uploadLen); } //WebSocket连接 function webSocketConn(){ try{ var readyState = new Array("正在连接", "已建立连接", "正在关闭连接" , "已关闭连接"); var host = "ws://localhost:8000"; websocket = new WebSocket(host); websocket.onopen = function(){ msg.innerHTML += "<p>Socket状态: " + readyState[websocket.readyState] + "</p>"; }; websocket.onmessage = function(event){ //每上传一个分片之后,等待介绍了服务端的提示之后再做下一个分片上传 if(event.data.indexOf("ok") != -1 && uploadState == 1){ if(endSize == file.size){ localStorage.removeItem(file.lastModifiedDate + "_" + file.name); msg.innerHTML += "<p>上传完成!!</p>"; websocket.close();//结束上传 }else{ uploadFile(); } } }; websocket.onclose = function(){ msg.innerHTML += "<p>Socket状态: " + readyState[websocket.readyState] + "</p>"; }; msg.innerHTML += "<p>Socket状态: " + readyState[websocket.readyState] + "</p>"; }catch(exception){ msg.innerHTML += "<p>有错误发生</p>"; return; } } /* 暂停上传 */ function pauseUpload(){ uploadState = 2; } /** * 从localStorage检查最后一次上传的字节 */ function getLastestUploadEndSize(uploadFile){ var lastestLen = localStorage.getItem(uploadFile.lastModifiedDate + "_" + uploadFile.name); if(lastestLen){ return parseInt(lastestLen); }else{ return 0; } } /* 发送文件名 */ function sendFileName(){ websocket.send(file.name); } /** * 选择文件之后触发事件 */ function fileSelected() { file = document.getElementById('fileToUpload').files[0]; if (file) { var fileSize = 0; if (file.size > 1024 * 1024) fileSize = (Math.round(file.size * 100 / (1024 * 1024)) / 100).toString() + 'MB'; else fileSize = (Math.round(file.size * 100 / 1024) / 100).toString() + 'KB'; document.getElementById('fileName').innerHTML = 'Name: ' + file.name; document.getElementById('fileSize').innerHTML = 'Size: ' + fileSize; document.getElementById('fileType').innerHTML = 'Type: ' + file.type; } }
Server:
package fileUpload; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.nio.ByteBuffer; import java.nio.charset.Charset; import java.security.MessageDigest; public class UploadServer { private int port = 8000; private ServerSocket serverSocket; public UploadServer() throws IOException { serverSocket = new ServerSocket(port); System.out.println("服务器启动"); } private void service() { Socket socket = null; while (true) { try { socket = serverSocket.accept(); Thread workThread = new Thread(new Handler(socket)); workThread.start(); } catch (IOException e) { e.printStackTrace(); } } } class Handler implements Runnable { private Socket socket; private boolean hasHandshake = false; Charset charset = Charset.forName("UTF-8"); private File file = null; private FileOutputStream fileOut = null; public Handler(Socket socket) { this.socket = socket; } private PrintWriter getWriter(Socket socket) throws IOException { OutputStream socketOut = socket.getOutputStream(); return new PrintWriter(socketOut, true); } public String echo(String msg) { return "echo:" + msg; } public void run() { try { System.out.println("New connection accepted" + socket.getInetAddress() + ":" + socket.getPort()); InputStream in = socket.getInputStream(); PrintWriter pw = getWriter(socket); //读入缓存 byte[] buf = new byte[1024]; //读到字节 int len = in.read(buf, 0, 1024); //读到字节数组 byte[] res = new byte[len]; System.arraycopy(buf, 0, res, 0, len); String key = new String(res); if(!hasHandshake && key.indexOf("Key") > 0){ key = key.substring(0, key.indexOf("==") + 2); key = key.substring(key.indexOf("Key") + 4, key.length()).trim(); key+= "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; MessageDigest md = MessageDigest.getInstance("SHA-1"); md.update(key.getBytes("utf-8"), 0, key.length()); byte[] sha1Hash = md.digest(); sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder(); key = encoder.encode(sha1Hash); pw.println("HTTP/1.1 101 Switching Protocols"); pw.println("Upgrade: websocket"); pw.println("Connection: Upgrade"); pw.println("Sec-WebSocket-Accept: " + key); pw.println(); pw.flush(); hasHandshake = true; //接收数据 byte[] first = new byte[1]; int read = in.read(first, 0, 1); while(read > 0){ int b = first[0] & 0xFF; //boolean fin = (b & 0x80) > 0; // int rsv = (b & 0x70) >>> 4; byte opCode = (byte) (b & 0x0F); if(opCode == 8){ socket.getOutputStream().close(); file = null; fileOut.flush(); fileOut.close(); fileOut = null; break; } b = in.read(); int payloadLength = b & 0x7F; if (payloadLength == 126) { byte[] extended = new byte[2]; in.read(extended, 0, 2); int shift = 0; payloadLength = 0; for (int i = extended.length - 1; i >= 0; i--) { payloadLength = payloadLength + ((extended[i] & 0xFF) << shift); shift += 8; } } else if (payloadLength == 127) { byte[] extended = new byte[8]; in.read(extended, 0, 8); int shift = 0; payloadLength = 0; for (int i = extended.length - 1; i >= 0; i--) { payloadLength = payloadLength + ((extended[i] & 0xFF) << shift); shift += 8; } } //掩码 byte[] mask = new byte[4]; in.read(mask, 0, 4); int readThisFragment = 1; ByteBuffer byteBuf = ByteBuffer.allocate(payloadLength); while(payloadLength > 0){ int masked = in.read(); masked = masked ^ (mask[(int) ((readThisFragment - 1) % 4)] & 0xFF); byteBuf.put((byte) masked); payloadLength--; readThisFragment++; } byteBuf.flip(); if(opCode == 1){ getChar(byteBuf.array()); }else outFile(byteBuf.array()); in.read(first, 0, 1); } } in.close(); } catch (Exception e) { e.printStackTrace(); } finally { try { if (socket != null) socket.close(); } catch (IOException e) { e.printStackTrace(); } } } private void responseClient(boolean finalFragment) throws IOException { ByteBuffer byteBuf = ByteBuffer.allocate(10); byteBuf.put("ok".getBytes("UTF-8")); OutputStream out = socket.getOutputStream(); int first = 0x00; //是否是输出最后的WebSocket响应片段,默认 if (finalFragment) { first = first + 0x80; first = first + 0x1; } out.write(first); if (byteBuf.limit() < 126) { out.write(byteBuf.limit()); } else if (byteBuf.limit() < 65536) { out.write(126); out.write(byteBuf.limit() >>> 8); out.write(byteBuf.limit() & 0xFF); } else { // Will never be more than 2^31-1 out.write(127); out.write(0); out.write(0); out.write(0); out.write(0); out.write(byteBuf.limit() >>> 24); out.write(byteBuf.limit() >>> 16); out.write(byteBuf.limit() >>> 8); out.write(byteBuf.limit() & 0xFF); } // Write the content out.write(byteBuf.array(), 0, byteBuf.limit()); out.flush(); } /** * 方法说明: * @开发:linrb * @创建时间:2012-8-21 * @param array * @throws IOException */ private void getChar(byte[] array) throws IOException { ByteArrayInputStream byteIn = new ByteArrayInputStream(array); InputStreamReader reader = new InputStreamReader(byteIn, charset.newDecoder()); int b = 0; String res = ""; try { while((b = reader.read()) > 0){ res += (char)b; } } catch (IOException e) { e.printStackTrace(); } file = new File("C:/" + res); } /** * 方法说明: * @开发:linrb * @创建时间:2012-8-14 * @param array * @throws IOException */ private void outFile(byte[] array) throws IOException { if(fileOut == null){ fileOut = new FileOutputStream(file, true); } fileOut.write(array); responseClient(true); } } public static void main(String[] args) throws IOException { new UploadServer().service(); } }
The above is the detailed content of HTML5 breakpoint resume upload sample code sharing. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

Guide to Table Border in HTML. Here we discuss multiple ways for defining table-border with examples of the Table Border in HTML.

This is a guide to Nested Table in HTML. Here we discuss how to create a table within the table along with the respective examples.

Guide to HTML margin-left. Here we discuss a brief overview on HTML margin-left and its Examples along with its Code Implementation.

Guide to HTML Table Layout. Here we discuss the Values of HTML Table Layout along with the examples and outputs n detail.

Guide to Moving Text in HTML. Here we discuss an introduction, how marquee tag work with syntax and examples to implement.

Guide to the HTML Ordered List. Here we also discuss introduction of HTML Ordered list and types along with their example respectively

Guide to HTML onclick Button. Here we discuss their introduction, working, examples and onclick Event in various events respectively.

Guide to HTML Input Placeholder. Here we discuss the Examples of HTML Input Placeholder along with the codes and outputs.
