程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> ESFramework4.0文件傳送 如此簡單(1)

ESFramework4.0文件傳送 如此簡單(1)

編輯:關於C語言

ESFramework,是一套可高度復用的、靈活的、單純而又強大的.Net通信框架,全部采用C#編寫。ESFramework內置了對Tcp和Udp的支持,並且支持文本協議和流協議,提供了多種網絡引擎供服務端和客戶端開發人員輕松使用。采用ESFramework框架,使得您不需要了解Socket、不用再關心底層與通信相關的一切瑣碎的事情,就可以在一個更高的層次上更快地開發屬於您的高效穩定的網絡通信應用。像IM系統、視頻會議系統、數據采集系統等,凡是需要分布式通信的系統都可以使用ESFramework框架。

一.ESPlus的文件傳送流程

ESPlus定義了文件傳送的標准流程,可以用下圖表示:

(1)由發送方發起傳送文件的請求。

(2)接收方回復同意或者拒絕接收文件。如果拒收,則流程結束;否則進入下一步。

(3)發送方發送文件數據,接收方接收文件數據。

(4)如果文件傳送過程中,接收方或發送方掉線或者取消文件傳送,則文件傳送被中斷,流程結束。如果文件傳送過程一直正常,則到最後完成文件的傳送。

有幾點需要說明一下:

(1)發送方可以是客戶端,也可以是服務器;接收方也是如此。但無論發送方和接收方的類別如何,它們都遵守這一文件傳送流程;就像ESFramework所有的通信引擎都公用同一套消息處理骨架流程一樣。

(2)當接收方同意接收後,框架會自動搜索是否存在匹配的續傳項目,若存在,則會啟動斷點續傳。當然,我們可以通過文件接收管理器的屬性來控制斷點續傳功能是否開啟。關於斷點續傳的更多內容,可以參考ESFramework 4.0 文件斷點續傳原理與實現。

(3)進行文件傳送的線程是由框架自動控制的,只要發送方收到了接收方同意接收的回復,框架就會自動在後台線程中發送文件數據包;同樣,此時接收方也會自動處理接收到的文件數據包。

(4)發送方或接收方都可隨時取消正在傳送的文件。

(5)當文件傳送被中斷或完成時,發送方和接收方都會有相應的事件通知。

二.ESPlus用於支持文件傳送的基礎設施

1.TransmittingFileInfo

無論是發送方還是接收方,針對每個文件傳送任務,都需要有個對象來表示它,TransmittingFileInfo便是一個文件傳送項目的封裝,裡面包含了類似發送者ID、接收者ID、文件名稱等相關信息。

TransmittingFileInfo的大部分屬性對於發送方和接收方都是有效的,而有幾個屬性只對發送方有效(比如SendingFileParas),有幾個屬性只對接收方有效(如LocalSaveFilePath),這些在幫助文檔中都有詳細的說明。而且,有些屬性(如OriginFileLastUpdateTime)的存在是用於支持斷點續傳功能的。

2.FileTransDisrupttedType

ESPlus使用FileTransDisrupttedType枚舉定義了所有可能導致文件傳送中斷的原因:

  1. public enum FileTransDisrupttedType  
  2. {  
  3. /// <summary>  
  4. /// 自己主動取消  
  5. /// </summary>  
  6. ActiveCancel,  
  7. /// <summary>  
  8. /// 對方取消  
  9. /// </summary>  
  10. DestCancel,  
  11. /// <summary>  
  12. /// 對方掉線  
  13. /// </summary>  
  14. DestOffline,  
  15. /// <summary>  
  16. /// 網絡中斷、自己掉線  
  17. /// </summary>  
  18. SelfOffline,  
  19. /// <summary>  
  20. /// 對方拒絕接收文件  
  21. /// </summary>  
  22. DestReject,  
  23. /// <summary>  
  24. /// 其它原因,如文件讀取失敗等  
  25. /// </summary>  
  26. OtherCause  
  27. }  

3.IFileTransferingEvents 接口

ESPlus定義了IFileTransferingEvents接口,用於暴露所有與文件傳送相關的狀態和事件:

  1. public interface IFileTransferingEvents  
  2. {  
  3. /// <summary>  
  4. /// 當某個文件開始傳送時,觸發該事件。  
  5. /// </summary>  
  6. event CbGeneric<TransmittingFileInfo> FileTransStarted;  
  7. /// <summary>  
  8. /// 當某個文件續傳開始時,觸發該事件。(將不再觸發FileTransStarted事件)  
  9. /// </summary>  
  10. event CbGeneric<TransmittingFileInfo> FileResumedTransStarted;  
  11. /// <summary>  
  12. /// 文件傳送的進度。參數為fileID(文件編號) ,total(文件大小) ,transfered(已傳送字節數)  
  13. /// </summary>  
  14. event CbFileSendedProgress FileTransProgress;   
  15. /// <summary>  
  16. /// 文件傳送中斷時,觸發該事件。  
  17. /// </summary>  
  18. event CbGeneric<TransmittingFileInfo, FileTransDisrupttedType> FileTransDisruptted;  
  19. /// <summary>  
  20. /// 文件傳送完成時,觸發該事件。  
  21. /// </summary>  
  22. event CbGeneric<TransmittingFileInfo> FileTransCompleted;   

通過預定這些事件,我們可以知道每個傳送的文件什麼時候開始(或斷點續傳)、什麼時候完成、傳遞的實時進度、傳送中斷的原因等等。要注意的是,這些事件都是在後台線程中觸發的,如果在事件處理函數中需要更新UI,則需要將調用轉發到UI線程。

4.SendingFileParas

該對象僅僅包含兩個屬性:SendingSpanInMSecs和FilePackageSize。發送方可以通過SendingFileParas對象來指定發送文件數據包時的頻率與每個數據包的大小。一般來說,為了達到最快的傳送速度,SendingSpanInMSecs可以設為0。而FilePackageSize的大小則要根據發送方與接收方的網絡環境的好壞進行決定,在Internet上,一般可以設為2048或4096左右;而在局網內,可以設為204800甚至更大(在局網的傳送速度可以達到30M/s以上)。

5.IFileController

通過ESPlus.Application.FileTransfering.IFileController接口,我們可以提交發送文件的請求,並且可以主動取消正在接收或發送的文件。IFileController即可用於客戶端也可用戶服務端。

  1. public interface IFileController  
  2. {  
  3. /// <summary>  
  4. /// 該事件接口暴露了所有正在發送文件的實時狀態。  
  5. /// </summary>  
  6. IFileTransferingEvents FileSendingEvents { get; }  
  7. /// <summary>  
  8. /// 該事件接口暴露了所有正在接收的文件的實時狀態。  
  9. /// </summary>  
  10. IFileTransferingEvents FileReceivingEvents { get; }  
  11. /// <summary>  
  12. /// 准備發送文件。如果對方同意接收,則後台會自動發送文件;如果對方拒絕接收,則會取消發送。  
  13. /// 如果要發送的文件不存在或被占用,則將拋出對應的異常。  
  14. /// </summary>   
  15. /// <param name="accepterID">接收文件的用戶ID</param>  
  16. /// <param name="filePath">被發送文件的路徑</param>  
  17. /// <param name="comment">其它附加備注。如果是在類似FTP的服務中,該參數可以是保存文件的路徑</param>   
  18. /// <param name="fileID">返回即將發送文件的唯一編號</param>  
  19. void BeginSendFile(string accepterID, string filePath, string comment, out string fileID);  
  20. /// <summary>  
  21. /// 准備發送文件。如果對方同意接收,則後台會自動發送文件;如果對方拒絕接收,則會取消發送。  
  22. /// 如果要發送的文件不存在或被占用,則將拋出對應的異常。  
  23. /// </summary>  
  24. /// <param name="accepterID">接收文件的用戶ID</param>  
  25. /// <param name="filePath">被發送文件的路徑</param>  
  26. /// <param name="comment">其它附加備注。如果是在類似FTP的服務中,該參數可以是保存文件的路徑</param>  
  27. /// <param name="paras">發送參數設定。傳入null,表示采用IFileSenderManager的默認設置。</param>  
  28. /// <param name="fileID">返回即將發送文件的唯一編號</param>  
  29. void BeginSendFile(string accepterID, string filePath, string comment,SendingFileParas paras, out string fileID);  
  30. /// <summary>  
  31. /// 主動取消正在發送或接收的文件,並通知對方。  
  32. /// </summary>   
  33. void CancelFileTransfering(string fileID);   
  34. /// <summary>  
  35. /// 取消與某個用戶相關的正在傳送項目。  
  36. /// </summary>   
  37. /// <param name="destUserID">目標用戶ID。</param>  
  38. void CancelFileTransferingAbout(string destUserID);   
  39. /// <summary>  
  40. /// 獲取正在發送或接收中的文件的相關信息。  
  41. /// </summary>   
  42. TransmittingFileInfo GetFileInfo(string fileID);  

(1)BeginSendFile用於向接收方提交發送文件的請求,如果對方同意,則後台會自動開始傳遞文件。該方法有個out參數fileID,用於傳出標記該文件傳送項目的唯一編號,比如,你打算將同一個文件發送給兩個好友,將會調用兩次BeginSendFile方法,而兩次得到的fileID是不一樣的。也就是說,fileID是用於標記文件傳送項目的,而不是標記文件的。

該方法有兩個重載,區別在於第二個BeginSendFile方法多了一個SendingFileParas參數,用於主動控制文件數據包的大小和發送頻率。

在客戶端使用時,BeginSendFile方法不僅可以向其他在線用戶提交發送文件的請求,也可以直接向服務器提交發送文件的請求 -- 即此時文件的接收者為服務端。我們只需要將accepterID參數傳入NetServer.SystemUserID,以指明由服務端而不是其他用戶來接收即將發送的文件。

(2)GetFileInfo方法可以獲取任何一個正在發送或正在接收的項目信息。

(3)CancelFileTransfering方法用於取消正在發送或接收的某個文件傳送項目,調用該方法時,框架會自動通知文件傳送的另一端用戶,並觸發FileReceivingEvents或FileSendingEvents中的FileTransDisruptted事件,而另一端也會自動觸發FileTransDisruptted事件。

(4)CancelFileTransferingAbout方法用於取消與某個指定用戶相關的正在傳送項目。比如,我們正在與aa01用戶聊天,並且與aa01有多個文件正在傳送,此時,如果要關閉與aa01的聊天窗口,那麼關閉之前,通常會先調用CancelFileTransferingAbout方法來取消與aa01相關的所有文件傳送。所以你經常會看到類似的提示:“您與aa01有文件正在傳送中,關閉當前窗口將導致正在傳送的文件中斷,您確定要關閉嗎?”。如果用戶確認關閉,此時就正是我們要調用CancelFileTransferingAbout方法的時候了。

(5)FileSendingEvents屬性用於暴露自己作為發送者的所有正在進行的文件傳送項目的實時狀態;FileReceivingEvents屬性用於暴露自己作為接收者的所有正在進行的文件傳送項目的實時狀態。

6.IFileHandler

IFileHandler接口將被框架回調以實現文件傳送機制。同IFileController一樣,其既可用於客戶端也可用戶服務端。

我們需要實現ESPlus.Application.FileTransfering.IFileHandler接口來獲取與文件傳送請求相關通知:

  1. public interface IFileBusinessHandler : IBusinessHandler  
  2. {   
  3. /// <summary>  
  4. /// 是否同意接收文件?  
  5. /// </summary>   
  6. /// <param name="senderID">發送者的ID。如果為NetServer.SystemUserID,則表示是服務端發送的。</param>  
  7. /// <param name="fileName">文件名稱。</param>  
  8. /// <param name="fileLength">文件大小。</param>  
  9. /// <param name="comment">其它附加備注。如果是在類似FTP的服務中,該參數可以是保存文件的路徑</param>  
  10. /// <param name="fileID">文件ID。</param>  
  11. /// <param name="resumedFileItem">如果能續傳,則不為null。</param>  
  12. /// <returns>返回值為保存文件的路徑,如果為null,表示拒絕接收/拒絕續傳文件。如果參數resumedFileItem不為null,而且返回路徑等於resumedFileItem.LocalFileSavePath,則表示續傳;否則表示另存。</returns>  
  13. string ReadyToAcceptFile(string senderID, string fileName, long fileLength, string comment, string fileID, ResumedFileItem resumedFileItem);   
  14. /// <summary>  
  15. /// 接收者對自己發送文件請求的回復 -- 同意/拒絕接收。  
  16. /// </summary>  
  17. /// <param name="info">文件傳送項目的相關信息</param>  
  18. /// <param name="agreed">對方是否同意</param>  
  19. void OnResponSEOfReceiver(TransmittingFileInfo info ,bool agreed);  

(1)ReadyToAcceptFile方法是當前用戶作為接收方時被框架回調的;而OnResponSEOfReceiver方法是當前用戶作為發送方時,被框架回調的。

(2)IFileHandler接口的兩個方法都將在後台線程中被框架調用,如果實現該方法時需要刷新應用程序的UI,則注意一定要轉發到UI線程。

(3)當發送方提交了發送文件的請求後,框架會在接收方回調ReadyToAcceptFileAsyn方法以詢問是否同意接收,如果同意,ReadyToAcceptFileAsyn應返回有效的存儲接收文件的路徑,否則,返回null。

(4)當接收方同意或拒絕接收文件,框架會在發送方回調OnResponseOfReceiver方法以通知發送者。通常,應用程序在實現OnResponSEOfReceiver方法時,最多只需要告知文件發送者,而不需要再做任何其它的額外處理。因為框架已經幫你打理好了一切。

當接收方同意接收文件後,與該文件傳送項目相關的事件會通過IFileOutter暴露的IFileTransferingEvents接口相繼觸發。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved