2009-10-13 44 views
0

我正在創建一個可以本地或遠程使用的WCF服務,有時使用第三方組件應用程序來處理文件,這些應用程序不幸需要輸入文件系統上實際文件的路徑,而不是.net流或類似的東西那。對於這種情況,是否有標準的方法,就合同運營的參數應該是什麼等等而言?儘管我認爲這不是至關重要的,因爲它最終必須在本地和遠程情況下都可以接受地執行,但我寧願在本地情況下不必從文件系統讀取整個文件,包括消息中的內容,並在文件系統上重新實現它,但是爲了遠程使用,這是必需的。有沒有辦法做到這一點,例如通過有一個FSRefDoc類型序列化不同取決於它是本地使用還是遠程使用?本地和遠程WCF服務的最佳實踐是處理文件系統上的大文件?

編輯:澄清:問題是我想在這兩種情況下完全發送不同的信息。如果我控制着一個本地服務,我可以發送一個路徑到本地文件系統上的文件,但如果它是遠程服務,我必須自己發送文件內容。當然,我可以在兩種情況下發送內容,但這意味着我在當地案件中表現不佳。也許我不應該爲此擔心。

+0

這聽起來像你有一個WCF服務,這需要你寫入本地文件系統。您仍然可以使用流式傳輸或分塊將文件的數據發送到服務。我不是說你談論的本地和遠程之間的差異是什麼? – RichardOD 2009-10-13 19:38:50

回答

0

那麼,你真的觸及到兩個不同的問題:

  • 本地與遠程服務的可用性
  • 「正常」 與流媒體服務(大文件)

一般情況下,如果您的服務在LAN上的公司防火牆後面工作,則應該使用NetTcpBinding,因爲它是最快和最高效的。它速度快,效率高,因爲它使用二進制消息編碼(而不是互聯網上的文本消息編碼)。

如果你必須爲「外部」世界提供服務,你應該嘗試使用盡可能互操作的綁定,而在這裏你的選擇是basicHttpBinding(完全可互操作 - 「舊」的SOAP 1.1協議),它不能擔保太多,wsHttpBinding提供了更多的靈活性和選擇,但支持程度較低。

既然你可以輕鬆地與三個端點創建一個單獨的服務,你真的可以創建你的服務,然後定義這三個端點:一個爲本地客戶使用NetTcpBinding的,使用basicHttpBinding的最廣泛的可用性之一,並且可選另一個用的wsHttpBinding 。

這是故事的一面。另一個是:對於你的「正常」服務調用,交換幾條信息(大小可達幾KB),你應該使用正常的「緩衝傳輸」默認行爲 - 消息是完全準備好的在緩衝區中並作爲一個整體發送。

但是,對於處理大文件,最好使用流式傳輸模式 - 如果您希望客戶端能夠從服務器下載文件,請使用「StreamedResponse」;如果您希望客戶端使用「StreamedRequest」能夠上傳文件,或者如果您以兩種方式發送文件,只是簡單的「流式傳輸」。

因此,除了三個「常規」端點之外,每個綁定應至少有另一個端點來處理數據的流式交換,即上載/下載文件。

這可能看起來像很多不同的端點 - 但這確實不是問題,您的客戶端可以連接到適合他們的任何端點 - 常規vs.流和內部/本地(netTcpBinding)與外部(basicHttpBinding),因爲他們需要 - 最後,只寫一次代碼!

啊,WCF的美麗! :-)

馬克

UPDATE:
OK,您的評論後,這是我會做什麼:

  • 創建一個單一的方法GetFile一個返回一個ILocalService服務合同路徑和文件名
  • 創建服務合同的實施
  • 主機上的服務端點netTcpBinding(因爲它的內部,本地)

[ServiceContract] 
interface ILocalService 
{ 
    [OperationContract] 
    string GetFile(......(whatever parameters you need here).....); 
} 

class LocalService : ILocalService 
{ 
    string GetFile(......(whatever parameters you need here).....) 
    { 
     // do stuff..... 
     return fileName; 
    } 
} 

其次:

  • 創建第二個合同IRemoteService服務與單一方法GetFile不返回文件名作爲字符串,而是返回流
  • 創建服務合同的實施
  • 主機上basicHttpBinding端點互聯網使用該服務
  • 確保有transferMode="StreamedResponse"在您綁定的配置,使流回文件

[ServiceContract] 
interface IRemoteService 
{ 
    [OperationContract] 
    Stream GetFile(......(whatever parameters you need here).....); 
} 

class RemoteService : IRemoteService 
{ 
    Stream GetFile(......(whatever parameters you need here).....) 
    { 
     // do stuff..... 
     FileStream stream = new FileStream(....); 
     return stream; 
    } 
} 
+0

非常感謝您的回答。但是恐怕這表明我的問題還不夠清楚,所以讓我再試一次: 問題是我想在兩種情況下完全發送不同的信息。如果我控制着一個本地服務,我可以發送一個路徑到本地文件系統上的文件,但如果它是遠程服務,我必須自己發送文件內容。當然,我可以在兩種情況下發送內容,但這意味着我在當地案件中表現不佳。也許我不應該爲此擔心。 – 2009-10-13 20:36:05

+0

謝謝。這或多或少是我決定要做的。 – 2009-11-06 15:33:46

1

OK,

在更新之後,我會考慮以下內容。

1)創建一個需要路徑的方法。通過一個命名的管道綁定公開並在本地使用。 2)創建一個文件(流/字節數組等)的方法。對非本地計算機使用適當的綁定(在不同的端點上)公開(在局域網場景中,TCP通常是您最好的選擇)。

然後,您需要做的就是確保您不重複相同的業務邏輯。所以簡而言之 - 創建2個不同的服務接口,2個不同的端點和2個不同的綁定。