HTML5 + WebSocket provides instances for simultaneous uploading of multiple files,
It is very troublesome for traditional HTTP applications to upload multiple files at the same time and view the upload progress, of course, there are also some SWF-based File Upload components to provide this convenience. in HTML5, the control on file reading and uploading is very flexible. HTML5 provides a series of AIPS for file reading, including reading a part of a file, it is more convenient and flexible to transfer files with Websocket. the following uses HTML5 and websocet to Easily upload multiple files to the application at the same time.
Implement Functions
Preview The functions you need:
The main function is that you can directly drag and drop folder files to a webpage and upload them to display the upload progress information during the upload process.
FileInfo class Encapsulation
To facilitate reading File information, an object class for reading simple File information is encapsulated on the basis of the original File.
function FileInfo(file, pagesize) { this.Size = file.size; this.File = file; this.FileType = file.type; this.FileName = file.name; this.PageSize = pagesize; this.PageIndex = 0; this.Pages = 0; this.UploadError = null; this.UploadProcess = null; this.DataBuffer = null; this.UploadBytes = 0; this.ID = Math.floor(Math.random() * 0x10000).toString(16); this.LoadCallBack = null; if (Math.floor(this.Size % this.PageSize) > 0) { this.Pages = Math.floor((this.Size / this.PageSize)) + 1; } else { this.Pages = Math.floor(this.Size / this.PageSize); } }FileInfo.prototype.Reset = function () { this.PageIndex = 0; this.UploadBytes = 0;}FileInfo.prototype.toBase64String = function () { var binary = '' var bytes = new Uint8Array(this.DataBuffer) var len = bytes.byteLength; for (var i = 0; i < len; i++) { binary += String.fromCharCode(bytes[i]) } return window.btoa(binary);}FileInfo.prototype.OnLoadData = function (evt) { var obj = evt.target["tag"]; if (evt.target.readyState == FileReader.DONE) { obj.DataBuffer = evt.target.result; if (obj.LoadCallBack != null) obj.LoadCallBack(obj); } else { if (obj.UploadError != null) obj.UploadError(fi, evt.target.error); } } FileInfo.prototype.Load = function (completed) { this.LoadCallBack = completed; if (this.filereader == null || this.filereader == undefined) this.filereader = new FileReader(); var reader = this.filereader; reader["tag"] = this; reader.onloadend = this.OnLoadData; var count = this.Size - this.PageIndex * this.PageSize; if (count > this.PageSize) count = this.PageSize; this.UploadBytes += count; var blob = this.File.slice(this.PageIndex * this.PageSize, this.PageIndex * this.PageSize + count); reader.readAsArrayBuffer(blob);}; FileInfo.prototype.OnUploadData = function (file) { var channel = file._channel; var url = file._url; channel.Send({ url: url, parameters: { FileID: file.ID, PageIndex: file.PageIndex, Pages: file.Pages, Base64Data: file.toBase64String()} }, function (result) { if (result.status == null || result.status == undefined) { file.PageIndex++; if (file.UploadProcess != null) file.UploadProcess(file); if (file.PageIndex < file.Pages) { file.Load(file.OnUploadData); } } else { if (file.UploadError != null) file.UploadError(file, data.status); } });} FileInfo.prototype.Upload = function (channel, url) { var fi = this; channel.Send({ url: url, parameters: { FileName: fi.FileName, Size: fi.Size, FileID: fi.ID} }, function (result) { if (result.status == null || result.status == undefined) { fi._channel = channel; fi._url = result.data; fi.Load(fi.OnUploadData); } else { if (file.UploadError != null) file.UploadError(fi, result.status); } }); }
Class processing is very simple. Some file information is implemented through file initialization and specifying the part size, such as the page size of the number of pages. of course, the most important thing is to encapsulate the file's Upload method, which is used to package the file block information into base64 information and send it to the server through Websocket.
Drag and Drop files
In HTML5, you do not need to perform complicated tasks by dragging system files. You only need to bind related events to container elements.
function onDragEnter(e) { e.stopPropagation(); e.preventDefault(); } function onDragOver(e) { e.stopPropagation(); e.preventDefault(); $(dropbox).addClass('rounded'); } function onDragLeave(e) { e.stopPropagation(); e.preventDefault(); $(dropbox).removeClass('rounded'); } function onDrop(e) { e.stopPropagation(); e.preventDefault(); $(dropbox).removeClass('rounded'); var readFileSize = 0; var files = e.dataTransfer.files; if (files.length > 0) { onFileOpen(files); } }
You only need to obtain the drag-and-drop files during the onDrop process. These may be helpful through some HTML5 tutorials.
In this case, you only need to build the FileInfo object for the selected file and call the upload method.
function onFileOpen(files) { if (files.length > 0) { for (var i = 0; i < files.length; i++) { var info = new FileInfo(files[i], 32768); uploads.push(info); info.UploadProcess = onUploadProcess; addUploadItem(info); } } }
Use the UploadProcess event to update the progress of the uploaded file.
function onUploadProcess(file) { $('#p_' + file.ID).progressbar({ value: (file.PageIndex / file.Pages) * 100, text: file.FileName + '[' + file.UploadBytes + '/' + file.Size + ']' }); }
C # Server
With Beetle's support for websocket, the implementation of the corresponding server is very simple.
/// <summary> /// Copyright © henryfan 2012 ///CreateTime: 2012/12/14 21:13:34 /// </summary> public class Handler { public void UploadPackage(string FileID, int PageIndex, int Pages, string Base64Data) { Console.WriteLine("FileID:{2},PageIndex:{0} Pages:{1} DataLength:{3}", PageIndex, Pages, FileID,Base64Data.Length); } public string UploadFile(string FileID, string FileName, long Size) { Console.WriteLine("FileID:{2},FileName:{0} Size:{1}", FileName, Size, FileID); return "Handler.UploadPackage"; } }
There are two server-side Methods: upload a file request and upload a file block receiving method.
Summary
The preceding simple code can be used to upload multiple files simultaneously. json is used to process the uploaded information. Therefore, a base64 encoding is required for the file stream, because the data submitted by websocket browsing generally has MASK Processing plus base64, the loss is relatively heavy. In fact, websocket provides the stream data packet format (arraybuffer ); of course, this kind of processing is not convenient and simple in terms of json operations.
Download Code: WebSocketUpload.rar
The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.