WCF分散式開發步步為贏(11):WCF流處理(Streaming)機制
Streaming,本文翻譯為流處理(張逸兄翻譯的Programming WCF Services一書裡把這個機制翻譯為“流操作”,不存在爭議。我選擇“流處理”一詞的意思,只是想把這個Streaming詞形象準確化,動名詞,流化處理、流處理,翻譯為流操作,初學者會誤會認為這個是一個服務操作。因為Streaming只是WCF內建的一個機制。而不是操作。)
我們首先來理解什麼是Streaming流處理。
【1】Streaming流處理的概念:
通常情況,客戶端和服務端進行互動,傳遞訊息,都是放到接收端的快取裡,待接收完畢後再進行處理。無論接收端是客戶端還是服務端都是如此。
【1.1】要解決的問題:
當客戶端呼叫服務時,要阻塞客戶單程式,直到訊息傳送完畢,服務端才開始處理資料,然後是返回處理完畢的結果給客戶端,客戶端接收完畢,才能解除阻塞。這樣帶來的問題是當訊息傳遞的時間很短,相對處理時間可以忽略不計,不會影響系統服務的效率。但是要是訊息資料很大,比如是圖片或者多媒體物件。每次傳輸時間相對較大,這樣接收端的等待時間過久,勢必每次阻塞都會很長,程式無法繼續執行。因而導致效率低下。
【1.2】Streaming流處理:
Streaming流處理就是WCF提供的主要針對大量訊息資料處理的一種優化機制。WCF允許接收端通過通道接受訊息的同時,啟動對訊息資料的處理,這樣的過程稱為流傳輸模型。
【2】Streaming流處理的特點:
顯然對於處理大量的訊息資料而言,流處理機制改善了系統的吞吐量和響應效率。
【2.1】流處理操作定義:
WCF的流處理機制需要使用.NET FrameWork定義的Stream類(它是FileStream, NetworkStream, MemoryStream 的父類)。流處理適用一下場景:
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->[ServiceContract]
interface IMyContract
{
[OperationContract]
Stream StreamReply1( );
[OperationContract]
void StreamReply2(out Stream stream);
[OperationContract]
void StreamRequest(Stream stream);
[OperationContract(IsOneWay = true)]
void OneWayStream(Stream stream);
}
它可以做為返回資料、引數、輸出引數的型別。當然也可以作為單調服務的操作引數。這裡使用的引數必須是可序列化的,例如MemoryStream。而FileStream不支援序列化因而不能作為引數或者返回資料的型別。
【2.2】流處理與繫結協議:
流處理機制在特定的繫結協議中才能使用,目前是BasicHttpBinding, NetTcpBinding, 和NetNamedPipeBinding 支援流處理模型。但是在預設情況下,WCF禁止流處理模式。
流傳輸模式使用使用TransferMode進行配置,TransferMode為列舉型別,其定義如下:
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->
public enum TransferMode
{
// Summary:
// The request and response messages are both buffered.
Buffered = 0,
//
// Summary:
// The request and response messages are both streamed.
Streamed = 1,
//
// Summary:
// The request message is streamed and the response message is buffered.
StreamedRequest = 2,
//
// Summary:
// The request message is buffered and the response message is streamed.
StreamedResponse = 3,
}
只有Streamed模式支援2.1中列舉的流處理模式場景。除了直接在服務上配置屬性以外,我們還可以再服務的配置檔案裡定義流傳輸模式。程式碼如下:
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--> <basicHttpBinding>
<binding name="basicHttpBinding" receiveTimeout="10:10:10" transferMode="Streamed" maxReceivedMessageSize="200000">
binding>
basicHttpBinding>
<netTcpBinding>
<binding name="netTcpBinding" receiveTimeout="10:10:10" transferMode="Streamed" maxReceivedMessageSize="200000">
binding>
netTcpBinding>
此為託管宿主的配置檔案,特定的繫結協議,可以配置其傳輸模式。
【2.3】注意:
流處理在使用http協議時,其預設訊息長度是64K,如果希望增加資料長度,需要在配置檔案裡重新設定。如: maxReceivedMessageSize="200000",具體程式碼如下:
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--><basicHttpBinding>
<binding name="basicHttpBinding" receiveTimeout="10:10:10" transferMode="Streamed" maxReceivedMessageSize="200000">
binding>
basicHttpBinding>
【3】示例程式碼分析:
這裡測試的流處理機制,使用的是處理圖片的上傳於下載,分別使用Stream和其子類MemoryStream作為引數或者返回訊息資料的型別。基本程式碼演示的是流處理三種模式場景:
【3.1】服務端:
服務契約分別定義了下載資料和上傳資料,下載資料使用的型別MemoryStream,上傳資料引數型別是是Stream。具體程式碼如下:
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--> //1.服務契約
[ServiceContract( Namespace = "http://www.cnblogs.com/frank_xl/")]
public interface IWCFService
{
//操作契約,獲取資料流
[OperationContract]
MemoryStream DownLoadStreamData(string fileName);
//操作契約,輸出資料流
[OperationContract]
void DownLoadStreamDataOut(out MemoryStream stream, string fileName);
//操作契約,上載資料流,單向操作的訊息轉換為資料流
[OperationContract(IsOneWay=true)]
void UpLoadStreamData(Stream stream);
}
//2.服務類,繼承介面。實現服務契約定義的操作
public class WCFService : IWCFService
{
//1實現介面定義的方法,下載檔案資料流
public MemoryStream DownLoadStreamData(string fileName)
{
// Stream stream =
byte[] file = new byte[200000];
String filePath = AppDomain.CurrentDomain.BaseDirectory + @"\" + fileName;
file = File.ReadAllBytes(filePath);
MemoryStream memoryStream = new MemoryStream(file);
return memoryStream;
}
//2實現介面定義的方法,下載檔案資料流
public void DownLoadStreamDataOut(out MemoryStream stream, string fileName)
{
// Stream stream =
byte[] file = new byte[200000];
String filePath = AppDomain.CurrentDomain.BaseDirectory + @"\" + fileName;
file = File.ReadAllBytes(filePath);
MemoryStream memoryStream = new MemoryStream(file);
stream = memoryStream;
}
//3實現介面定義的方法,上傳檔案資料流
public void UpLoadStreamData(Stream stream)
{
// codes here to deal with the stream Stream stream =
Console.WriteLine("The Stream length is {0}",stream.Length);
}
}
【3.2】託管宿主:
我們分別使用basicHttpBinding和netTcpBinding定義了兩個服務終結點,這裡不要忘記設定最大接受訊息資料大小maxReceivedMessageSize="200000",如果設定較小會導致接受資料超過設定的錯誤。具體程式碼如下:
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--> <system.serviceModel>
<services>
<service behaviorConfiguration="WCFService.WCFServiceBehavior"
name="WCFService.WCFService">
<endpoint
address="http://localhost:8002/WCFService"
binding="basicHttpBinding"
contract="WCFService.IWCFService">
endpoint>
<endpoint
address="net.tcp://localhost:8004/WCFService"
binding="netTcpBinding"
contract="WCFService.IWCFService">
endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8001/"/>
<add baseAddress="net.tcp://localhost:8003/"/>
baseAddresses>
host>
service>
services>
<behaviors>
<serviceBehaviors>
<behavior name="WCFService.WCFServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
behavior>
serviceBehaviors>
behaviors>
<bindings>
<basicHttpBinding>
<binding name="basicHttpBinding" receiveTimeout="10:10:10" transferMode="Streamed" maxReceivedMessageSize="200000">
binding>
basicHttpBinding>
<netTcpBinding>
<binding name="netTcpBinding" receiveTimeout="10:10:10" transferMode="Streamed" maxReceivedMessageSize="200000">
binding>
netTcpBinding>
bindings>
system.serviceModel>
【3.3】客戶端:
客戶端分別測試資料的上傳和下載,使用不同的方法。這裡的測試目前
【4】總結:
本文介紹了WCF流處理模型,但是實現程式碼出現問題。
(1)作為WCF的流處理機制,確實為我們的大規模訊息資料傳輸提供了理想的機制,提高了系統的效率和響應速度。
(2)Stream作為.net類庫的內部型別,在.net平臺上使用來說較為方便,但是與異構平臺的互動勢必受到諸多限制,也違背了WCF跨平臺的初衷。
(3) 我在除錯這個示例程式碼的過程中遇到了幾個錯誤,基本都整理出來放到WCF分散式開發常見錯誤裡了。使用netTcpBinding繫結進行資料傳輸的時候,一個很有價值的錯誤就是:the socket connection was aborted. this could be caused by an error processing your message or a receive timeout being exceeded by the remote host ...這個錯誤我google國內和國外的一些資料,但是解決的辦法都是更換協議。其實是一種很無奈的措施,目前我還沒有找出更好的解決辦法就是基於netTcpBinding。表面的原因是服務處理超時。但是具體的錯誤資訊沒有這樣簡單。我更換協議以後其他的流服務操作呼叫出了問題。所以這個只能針對特定的操作有幫助。我把這個錯誤收集起來供大家參考。也希望發揮大家的作用把這個問題解決。
也許這個錯誤應該反映給WCF的開發小組,無論國內還是國外的技術論壇,包括MSDN都有人遇到這樣的問題,而沒有一個最佳的解決方案。這裡我對流處理示例程式碼分別打包,目前都有問題。
<1>流處理機制示例1裡程式碼測試上傳檔案,成功,下載檔案錯誤。
/Files/frank_xl/WCFServiceStreamingFrankXuLei.rar
<2>這裡使用的是位元組陣列,測試下載檔案,下載檔案是成功的,上傳檔案失敗。/Files/frank_xl/WCFServiceStreamingByteArrayFrankXuLei.rar
兩個失敗的原因都是一樣,套接字中斷,連線超時。WCF分散式開發常見錯誤解決(10):套接字連線中斷,The socket connection was aborted ,我進行了整理,也查詢了國外的論壇,沒有找到理想的解決辦法。我已經嘗試了修改接受時間的限制,但是不起作用。我會繼續關注這個問題,也希望有興趣的朋友補充。MSDN論壇上有人提供瞭解決的方法,但是不理想,更換協議。希望微軟WCF的開發、測試小組早日注意這個問題。
參考文章:
1.《Programming WCF Services》;
2.WSE3.0構建Web服務安全(4):MTOM訊息傳輸優化和檔案上傳、下載
【老徐的部落格】
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-604819/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- WCF分散式開發步步為贏(14):WCF安全程式設計–基本概念分散式程式設計
- WCF分散式開發步步為贏(0):WCF學習經驗分享,如何更好地學習WCF?薦分散式
- WCF分散式開發步步為贏(13):WCF服務離線操作與訊息佇列MSMQ分散式佇列MQ
- WCF分散式開發常見錯誤(27):Securechannelcannotbeopened分散式
- WCF分散式開發常見錯誤(28):Therequestedupgradeisnotsupportedby…分散式
- 學習 WCF (3)--開發WCF客戶程式
- WCF 的 Service Instance模式和併發處理模式
- 【Frank.Xu】WCF分散式開發必備知識(1):MSMQ訊息佇列分散式MQ佇列
- WCF後傳系列(10):訊息處理功能核心
- WCF分散式安全開發實踐(11):訊息安全模式之Certificate身份驗證:Message_Certificate_WSHttpBinding分散式模式HTTP
- 集團多應用系統分散式處理自動資料流機制研究分散式
- WCF基礎教程之開篇:建立、測試和呼叫WCF
- MSMQ In WCFMQ
- WCF學習筆記(一):WCF簡介筆記
- WCF筆記–併發管理筆記
- WCF的WindowsService開發參考【附原始碼】Windows原始碼
- WCF開發入門的六個步驟
- WCF、Web API、WCF REST、Web Service之區別WebAPIREST
- 分散式事務處理兩階段提交機制和原理分散式
- WCF筆記筆記
- WCF基礎
- WCF Rest ServiceREST
- WCF分散式安全開發實踐(1):傳輸安全模式之匿名客戶端:Transport_None_WSHttpBinding分散式模式客戶端NoneHTTP
- 步步為“贏”管理專案(轉)
- WCF Security:Silverlight authentication for WCF service based on security token
- 構建高效能分散式搜尋引擎(Wcf-示例篇)三薦分散式
- WCF分散式安全開發實踐(12):訊息安全模式之自定義X509證書驗證分散式模式
- WCF系列教程地址
- WCF配置檔案
- 擴充套件WCF自定義行為(二)套件
- 構建高效能分散式搜尋引擎(Wcf-基礎篇)一薦分散式
- WCF分散式安全開發實踐(9):訊息安全模式之Windows身份驗證:Message_Windows_NetTcpBinding分散式模式WindowsTCP
- 分散式鎖機制分散式
- WCF雙工通訊
- C# WCF入門C#
- WCF安全指南釋出
- WCF、Socket程式設計程式設計
- WCF 第一章 基礎 為一個ASMX服務實現一個WCF客戶端ASM客戶端