我的WCF摸爬滾打之路(1)


  等了好久終於等到今天!盼了好久終於把夢實現……哈哈,僅以此歌詞來慶祝我為期3天的wcf學習之路圓滿結束。

  今天寫這個文章的目的在於記錄一下我自己在學習WCF的時候碰到的一些問題,俗話說,好記心不如爛筆頭嘛。也為看見我這篇文章的有緣人(正在wcf中探索的人們,提供一點借鑒吧)。

  還是老樣子,圖文並茂的文章才是好文章(我自己定義的,勿噴!)。那么接下來我將把我這一路的細節以及碰到的問題和解決方法一一展示出來。

  我在學習wcf的時候第一件事就是自己做了個wcf的例子,因為wcf的傳輸協議有很多,比如說http、tcp。我主要講講tcp協議的wcf吧,因為這個確實比較麻煩的一個東西,有時候出現bug也是一些稀奇古怪的exception。廢話不多說直接上圖。

新建一個項目

 

新建好了的wcf服務庫如下圖

會自動生成幾個類文件。這幾個類文件分別是兩個interface和兩個interface的實現類(需要自己手動實現)。可能有的人會問,我怎么只生成了一個interface和它的實現類額?因為我想實現的是wcf通過一個servicehost和一個端口同時發布多個服務出來。另外兩個是我自己新建的 。哈哈……
 
 
看看具體的代碼都是啥!很簡單只是聲明了一個GetData(int value)函數。翻翻書或者百度一下都知道wcf的基本概念:以契約(Contract)來定義雙方通信,契約必須以接口的形式體現。這里面比較重要的兩個特性[ServiceContract]、[OperationContract]。一個服務契約,一個操作契約,只有定義了這兩個別人才認識你是個wcf服務撒。用這個時必須引用命名空間:using System.ServiceModel;
 1 namespace WcfServiceLibrary
 2 {
 3     // 注意: 使用“重構”菜單上的“重命名”命令,可以同時更改代碼和配置文件中的接口名“IService1”。
 4     [ServiceContract]
 5     public interface IService1
 6     {
 7         [OperationContract]
 8         string GetData(int value);
 9 
10       
11     }
12 
13   
14 }

既然wcf叫服務那他總的有服務吧!不然怎么服務於我。別急,上代碼:上面是契約、下面是服務。實際的服務代碼要由契約接口派生實現。

 1 namespace WcfServiceLibrary
 2 {
 3     // 注意: 使用“重構”菜單上的“重命名”命令,可以同時更改代碼和配置文件中的類名“Service1”。
 4     public class Service1 : IService1
 5     {
 6         public string GetData(int value)
 7         {
 8             if (value==1)
 9             {
10                 throw new NotImplementedException();
11             }
12             return string.Format("You entered: {0}", value);
13         }
14 
15        
16     }
17 }

以上工作完成后,wcf的創建算是完工了。接下來的重點,是建立wcf的宿主程序。
我就做了和控制台程序作為wcf說的宿主程序!

一般常見的是通過config文件進行配置,以為要深究的話,config文件是在有很東西要講,而我也只是初出茅廬。所以我就一代碼的形式進行配置文件的生成。而且只需要幾個常用的屬性就ok。且看代碼

1.我先實例化綁定形式NetTcpBinding

 1  private static NetTcpBinding netTcpBinding = new NetTcpBinding();
 2         public static NetTcpBinding InitNetTcpBinding()
 3         {
 4             netTcpBinding.Security.Mode = SecurityMode.None;
 5             netTcpBinding.ReceiveTimeout = TimeSpan.Parse("00:10:00");
 6             netTcpBinding.MaxBufferPoolSize = 2147483647; //
 7             netTcpBinding.MaxBufferSize = 2147483647;
 8             //netTcpBinding.MaxConnections = 10;
 9             //netTcpBinding.PortSharingEnabled = true;
10 
11             netTcpBinding.ReaderQuotas.MaxDepth = 2147483647;
12             netTcpBinding.ReaderQuotas.MaxStringContentLength = 2147483647;
13             netTcpBinding.ReaderQuotas.MaxArrayLength = 2147483647;
14             netTcpBinding.ReaderQuotas.MaxBytesPerRead = 2147483647;
15             netTcpBinding.ReaderQuotas.MaxNameTableCharCount = 2147483647;
16             netTcpBinding.MaxReceivedMessageSize = 2147483647;
17             return netTcpBinding;
18         }
View Code

2.我通過反射的形式拿到wcf的契約和服務。

 1  public static void LoadAssemBly(string assemblyName)
 2         {
 3             Assembly assem = Assembly.Load(assemblyName);
 4             Dictionary<Type, Type> svTypes = new Dictionary<Type, Type>();
 5             List<TypeInfo> list = assem.DefinedTypes.ToList();
 6             foreach (TypeInfo typeInfo in list)
 7             {
 8                 if (typeInfo.Attributes.ToString().IndexOf("Abstract") >= 0)
 9                 {
10                     TypeInfo tempK = typeInfo;                   
11                     var result = (from t in list where t.Name==(tempK.Name.Substring(1)) select t).ToList();
12                     TypeInfo tempV = result[0];
13                     svTypes.Add(tempK, tempV);
14                 }
15                
16             }            
17             string serviceAddress = string.Format("net.tcp://{0}:{1}", "localhost", "13141");
18             string endpointAddress = string.Empty;
19             string tName = string.Empty;
20             foreach (var item in svTypes)
21             {
22                 tName = item.Key.Name.Substring(1);
23                 endpointAddress = serviceAddress +"/"+ tName;
24 
25                 ServiceHost serviceHost = new ServiceHost(item.Value, new Uri(endpointAddress));
26 
27                 //加載元數據節點
28                 ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
29                 serviceHost.Description.Behaviors.Add(smb);
30                 serviceHost.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexTcpBinding(), "mex");
31 
32                 serviceHost.AddServiceEndpoint(item.Key, netTcpBinding, endpointAddress);
33 
34                 serviceHost.Opened += delegate
35                 {
36                     msg.AppendLine(string.Format("{0}開始監聽 Uri 為 :{1}/mex", tName, endpointAddress.ToString()));
37                 };
38                 serviceHost.Open();
39                 serviceHosts.Add(serviceHost);
40 
41             }
View Code

這樣我們得宿主程序就完成了。運行一下看看結果

這樣看來是沒問題了,那么們測試一下添加服務引用是否能找到服務。如果找到了就說明確實是沒問題了。

 

 OK,搞定!看似一帆風順。其實這中間我遇到了很多問題,下次再專門寫個博客講解吧

《轉載注明出處!》

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM