>  기사  >  웹 프론트엔드  >  동시에 여러 파일 업로드의 HTML5 WebSocket 구현

동시에 여러 파일 업로드의 HTML5 WebSocket 구현

黄舟
黄舟원래의
2017-02-22 13:54:592015검색

기존 HTTP 애플리케이션에서는 여러 파일을 동시에 업로드하고 업로드 진행 상황을 확인하는 것이 매우 번거롭습니다. 물론 HTML5에서는 이러한 편의를 제공하는 일부 SWF 기반 파일 업로드 구성 요소도 있습니다. 파일 읽기 및 업로드 제어가 매우 유연합니다. HTML5는 파일의 특정 부분의 내용을 계산하는 것을 포함하여 파일 전송이 더욱 편리해집니다. 다음은 websoce와 결합된 HTML5를 사용하여 여러 파일 업로드 애플리케이션을 동시에 구현하는 간단한 방법입니다.

구현 기능

해야 할 기능:

동시에 여러 파일 업로드의 HTML5 WebSocket 구현

주요 기능은 사용자가 폴더에 있는 파일을 웹페이지에 직접 드래그 앤 드롭하여 업로드할 수 있고, 업로드는 업로드 프로세스 중에 진행 정보가 표시됩니다.

FileInfo 클래스 캡슐화

파일 정보 읽기를 용이하게 하기 위해 파일 정보 읽기를 위한 간단한 객체 클래스가 캡슐화됩니다.

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

        }

    });

 

}



클래스 처리는 매우 간단합니다. 파일을 초기화하고 블록 크기를 지정하면 됩니다. 물론 가장 중요한 것은 파일 블록 정보를 저장하는 데 사용되는 파일에 해당하는 Upload 메서드를 캡슐화하는 것이며 Websocket을 통해 서버로 전송됩니다. >

파일 드래그 앤 드롭
HTML5에서는 시스템 파일 드래그 앤 드롭을 허용하기 위해 복잡한 작업을 수행할 필요가 없으며 관련 이벤트를 컨테이너 요소에 바인딩하기만 하면 됩니다.


function onDragEnter(e) {

            e.stopPropagation();

            e.preventDefault();

        }

 

        function onDragOver(e) {

            e.stopPropagation();

            e.preventDefault();

            $(dropbox).addClass(&#39;rounded&#39;);

        }

 

        function onDragLeave(e) {

            e.stopPropagation();

            e.preventDefault();

            $(dropbox).removeClass(&#39;rounded&#39;);

        }

 

        function onDrop(e) {

            e.stopPropagation();

            e.preventDefault();

            $(dropbox).removeClass(&#39;rounded&#39;);

            var readFileSize = 0;

            var files = e.dataTransfer.files;

            if (files.length > 0) {

                onFileOpen(files);

            }

 

        }


onDrop 프로세스 중에 관련 드래그 앤 드롭 파일만 얻으면 되며 일부 HTML5 튜토리얼을 통해 도움을 받을 수 있습니다.

이때 선택한 파일에 대한 관련 FileInfo 개체를 빌드하고


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

                }

            }

        }


업로드 방법만 호출하면 됩니다. UploadProcess 이벤트 파일 진행 정보는


function onUploadProcess(file) {

            $(&#39;#p_&#39; + file.ID).progressbar({ value: (file.PageIndex / file.Pages) * 100,

                text: file.FileName + &#39;[&#39; + file.UploadBytes + &#39;/&#39; + file.Size + &#39;]&#39;

            });

        }



C# 서버
설정으로 업데이트됩니다. Beetle의 websocket 지원 사용 services 최종 구현은 매우 간단합니다


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

        }

    }


서버 측 방법에는 두 가지가 있는데, 하나는 파일 요청을 업로드하는 것이고, 다른 하나는 파일 블록을 업로드하는 것입니다.


요약
위의 간단한 코드만으로 여러 파일을 동시에 업로드하는 기능을 구현할 수 있습니다. 여기서는 업로드된 정보를 처리하기 위해 json을 사용합니다. 따라서 파일 스트림은 base64로 인코딩되어야 합니다. websocket 브라우징으로 제출된 데이터는 일반적으로 MASK 처리를 사용하고 base64의 손실이 상대적으로 크기 때문에 실제로 websocket은 스트림 패킷 형식(어레이 버퍼)을 제공합니다. 처리가 json 작업만큼 편리하고 간단하지 않습니다.

다운로드 코드: WebSocketUpload.rar


위는 HTML5 WebSocket을 여러 개 구현한 예제의 내용입니다. 파일 업로드와 동시에 자세한 내용은 PHP 중국어 홈페이지(www.php.cn)를 참고해주세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.