溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

H5+WebSocket如何實(shí)現(xiàn)多文件同時(shí)上傳

發(fā)布時(shí)間:2021-06-28 14:33:37 來(lái)源:億速云 閱讀:162 作者:小新 欄目:web開(kāi)發(fā)

這篇文章主要介紹了H5+WebSocket如何實(shí)現(xiàn)多文件同時(shí)上傳,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

在傳統(tǒng)的HTTP應(yīng)用上傳文件想要同時(shí)上傳多個(gè)文件并查看上傳進(jìn)度是一件很麻煩的事情,當(dāng)然現(xiàn)在也有一些基于SWF的文件上傳組件提供這種的便利性.到了HTML5下對(duì)文件的讀取和上傳的控制方面就非常靈活,HTML5提供一系列的AIP進(jìn)行文件讀取,包括計(jì)取文件某一塊的內(nèi)容也非常方便,結(jié)合Websocket進(jìn)行文件的傳輸就變得更加方便和靈活.下面通過(guò)使用HTML5結(jié)合websocet簡(jiǎn)單地實(shí)現(xiàn)多文件同時(shí)上傳應(yīng)用.

實(shí)現(xiàn)功能

大概預(yù)覽一下需要做的功能:

H5+WebSocket如何實(shí)現(xiàn)多文件同時(shí)上傳

主要功能是用戶(hù)可以直接把文件夾的文件直接拖放到網(wǎng)頁(yè)中,并進(jìn)行上傳,在上傳的過(guò)程中顯示上傳進(jìn)度信息.

FileInfo類(lèi)封裝

為了方便讀取文件信息,在原有File的基礎(chǔ)封裝了一個(gè)簡(jiǎn)單文件信息讀取的對(duì)象類(lèi).

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);
        }
    });
 
}

類(lèi)的處理很簡(jiǎn)單,通過(guò)file初始化并指定分塊大小來(lái)實(shí)始化一些文件信息,如頁(yè)數(shù)量頁(yè)大小等.當(dāng)然最重要還封裝文件對(duì)應(yīng)的Upload方法,用于把文件塊信息打包成base64信息通過(guò)Websocket的方式發(fā)送到服務(wù)器.

文件拖放

在HTML5中接受系統(tǒng)文件拖放進(jìn)來(lái)并不需要做復(fù)雜的事情,只需要針對(duì)容器元素綁定相關(guān)事件即可.

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);
            }
 
        }

只需要在onDrop過(guò)程中獲取相關(guān)拖放文件即可,這些可能通過(guò)一些HTML5的教程可以得到幫助。

這時(shí)候只需要針對(duì)選擇的文件構(gòu)建相關(guān)FileInfo對(duì)象,并調(diào)用上傳方法即可.

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);
                }
            }
        }

通過(guò)UploadProcess事件對(duì)上傳文件進(jìn)度信息進(jìn)行一個(gè)設(shè)置更新

function onUploadProcess(file) {
            $('#p_' + file.ID).progressbar({ value: (file.PageIndex / file.Pages) * 100,
                text: file.FileName + '[' + file.UploadBytes + '/' + file.Size + ']'
            });
        }

C#服務(wù)端

借助于Beetle對(duì)websocket的支持對(duì)應(yīng)服務(wù)端的實(shí)現(xiàn)就非常簡(jiǎn)單了

/// <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";
        }
    }

服務(wù)端方法有兩個(gè)一個(gè)是上傳文件請(qǐng)求,和一個(gè)上傳文件塊接收方法.

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“H5+WebSocket如何實(shí)現(xiàn)多文件同時(shí)上傳”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來(lái)學(xué)習(xí)!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI