概述
與Socket相比,WCF真是爽得不得了,其基本指導思想為SOA——面向服務。
其基本配置在於ABC(Address,Binding,Contract),通常,只要這三個因素配置對了,那么,基本上就無限接近目標了。
剩下的配置,就可能是行為(Behavior),安全(Security)等。
在所有綁定中,為什么要選擇net.tcp,是因為其比較快(我這也是道聽途說,究竟有多快,沒有進行過測試);但是,缺點就是,net.tcp方式只能是WCF對WCF的通信。
而其繁瑣復雜的配置,網上已經有諸多工程師做了很多無私的奉獻。
步驟
原文參考:http://hi.baidu.com/guolulang/item/b5bdb01ccb23810ce65c36d6
http://www.cnblogs.com/Gyoung/archive/2012/12/11/2812555.html
Step1:設置“打開或關閉Windows功能”
打開紅色框內的功能
Step2:設置IIS
選中Default Web Site ——點擊“綁定”——確保網站綁定對話框中有“net.tcp”(默認端口號808),如果沒有,則“添加”
選中項目——高級設置——確保有“net.tcp”
Step3:設置“服務”
Step4:設置配置文件
只需將下文中的******替換即可。
S4.1服務端模板
替換Address(主機名+端口+文件路徑形式的名稱);
替換Contract(服務接口全名)
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.serviceModel> <!--描述綁定--> <bindings> <netTcpBinding> <binding name="netTcpBindConfig" closeTimeout="00:30:00" openTimeout="00:30:00" receiveTimeout="00:30:00" sendTimeout="00:30:00" transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxConnections="10" maxReceivedMessageSize="2147483647"> <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" /> <reliableSession ordered="true" inactivityTimeout="00:01:00" enabled="false" /> <security mode="None"> <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign"></transport> <message clientCredentialType="Windows" /> </security> </binding> </netTcpBinding> </bindings> <!--描述服務--> <services> <service name="DataSync.Services.DataSyncServiceImpl" behaviorConfiguration="WFServiceBehavior"> <host> <baseAddresses> <add baseAddress="net.tcp://localhost:808/DSServiceImpl"/> </baseAddresses> </host> <endpoint address="" contract="DataSync.Interfaces.IDataSyncEntry" binding="netTcpBinding" bindingConfiguration="netTcpBindConfig" /> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> </service> </services> <!--描述行為--> <behaviors> <serviceBehaviors> <behavior name="WFServiceBehavior"> <serviceMetadata httpGetEnabled="true"/> <serviceDebug includeExceptionDetailInFaults="true"/> <dataContractSerializer maxItemsInObjectGraph="6553600"/> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> <system.webServer> <modules runAllManagedModulesForAllRequests="true"/> <!-- 若要在調試過程中瀏覽 Web 應用程序根目錄,請將下面的值設置為 True。 在部署之前將該值設置為 False 可避免泄露 Web 應用程序文件夾信息。 --> <directoryBrowse enabled="true"/> </system.webServer> <system.web> <compilation debug="true" targetFramework="4.0" /> </system.web> </configuration>
S4.2客戶端模板
替換Address(指定寄宿的地址,如****/***.svc,而不是上文的DSServiceImpl);
替換Contract(服務接口全名)
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <bindings> <netTcpBinding> <binding name="NetTcpBinding_IDataSyncEntry"> <security mode="None" /> </binding> </netTcpBinding> </bindings> <client> <endpoint address="net.tcp://75wojoax/WcfWays/DataSyncServiceImpl.svc" binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IDataSyncEntry" contract="Remote.IDataSyncEntry" name="NetTcpBinding_IDataSyncEntry" /> </client> </system.serviceModel> </configuration>
問題
P1 需重啟IIS
問題描述:未能從程序集“System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”中加載類型“System.ServiceModel.Activation.HttpModule”。
解決辦法(執行以下命令,以重啟IIS):
如果安裝了 .NET Framework 4,隨后啟用了 .NET Framework 3.5 WCF HTTP 激活,則會發生此錯誤。若要解決該問題,請在 Visual Studio 2010 命令提示符下運行下面的命令行: aspnet_regiis.exe -i -enable 參見:http://msdn.microsoft.com/zh-cn/library/aa751852.aspx |
P2 需匹配的協議
問題描述:找不到具有綁定 NetTcpBinding 的終結點的與方案 net.tcp 匹配的基址。注冊的基址方案是 [http]。
解決方案:確保服務端和客戶端均使用NetTcpBinding協議。
參考:http://www.cnblogs.com/liulun/archive/2011/11/25/2263873.html
P3需匹配的協議
問題描述:無法調度消息,因為終結點地址“net.tcp://localhost/DataSyncServiceImpl.svc”上的服務對該地址的協議不可用。
解決方案:
1)確保服務端和客戶端均使用NetTcpBinding協議;
2)如果服務端使用了安全配置,如
<security mode="None"> <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign"></transport> <message clientCredentialType="Windows" /> </security>
則,客戶端也需要使用同類的協議,如
<bindings> <netTcpBinding> <binding name="NetTcpBinding_IDataSyncEntry"> <security mode="None" /> </binding> </netTcpBinding> </bindings>
或者代碼中
var binding = new NetTcpBinding(); binding.Security = new NetTcpSecurity() { Mode = SecurityMode.None };
P4 契約返回DataTable
問題描述:使用DataTable作為返回值
解決方案:
1) 網上傳說——使用命名的DataTable,即為DataTable的TableName賦一個名稱(試了一下,不行);
2) 傳遞DataSet可以。
public System.Data.DataSet TestDataTable() { DataTable dt = new DataTable("result"); dt.TableName = "navigateData"; dt.Columns.Add("Name",typeof(string)); var dr = dt.NewRow(); dr["Name"] = "pz"; dt.Rows.Add(dr); dr = dt.NewRow(); dr["Name"] = "pz2"; dt.Rows.Add(dr); var ds = new DataSet(); ds.Tables.Add(dt); return ds; }
P5 使用Channel Factory
問題描述:客戶端可以直接“引用服務”以生成***Client,但是,這不利於修改。
當修改了接口之后,沒有辦法及時通知到客戶端,除了“更新服務飲引用”之外。
解決方案:客戶端引用服務接口,並使用Channel Factory進行解耦,則客戶端只依賴接口。
public static DataSync.Interfaces.IDataSyncEntry CreateDataSyncEntryServices() { EndpointAddress addr = new EndpointAddress("net.tcp://75wojoax/WcfWays/DataSyncServiceImpl.svc"); var binding = new NetTcpBinding(); binding.Security = new NetTcpSecurity() { Mode = SecurityMode.None }; var channel = new ChannelFactory<DataSync.Interfaces.IDataSyncEntry>(binding, addr); var service = channel.CreateChannel(); return service; }