等了好久终于等到今天!盼了好久终于把梦实现……哈哈,仅以此歌词来庆祝我为期3天的wcf学习之路圆满结束。
今天写这个文章的目的在于记录一下我自己在学习WCF的时候碰到的一些问题,俗话说,好记心不如烂笔头嘛。也为看见我这篇文章的有缘人(正在wcf中探索的人们,提供一点借鉴吧)。
还是老样子,图文并茂的文章才是好文章(我自己定义的,勿喷!)。那么接下来我将把我这一路的细节以及碰到的问题和解决方法一一展示出来。
我在学习wcf的时候第一件事就是自己做了个wcf的例子,因为wcf的传输协议有很多,比如说http、tcp。我主要讲讲tcp协议的wcf吧,因为这个确实比较麻烦的一个东西,有时候出现bug也是一些稀奇古怪的exception。废话不多说直接上图。
新建一个项目
新建好了的wcf服务库如下图
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 }
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 }
这样我们得宿主程序就完成了。运行一下看看结果
这样看来是没问题了,那么们测试一下添加服务引用是否能找到服务。如果找到了就说明确实是没问题了。
OK,搞定!看似一帆风顺。其实这中间我遇到了很多问题,下次再专门写个博客讲解吧
《转载注明出处!》
- 12楼IT白痴
- mark!
- 11楼小i屁孩学编程
- 加油,你踏出了第一步。
- Re: stonewl
- @小i屁孩学编程,共同进步
- 10楼ensleep
- 额——怎么都是说WCF不好的————。,WCF与RA不冲突,内部用WCF,对外用RA是最好的。我们现在是总业务逻辑全在WCF,然后对于其它的不论是哪种网络连接都提供,同时我们有一批RA服务,其实也只是一个代理,最终也是调用WCF服务。WCF的主订阅、双工对于企业来讲是非常有用的。现在的世界不光只有互联网好么——不明白说WCF不行的都是不怎么想的,应该是只做做手机APP做做网站的人吧~~
- Re: stonewl
- @ensleep,对头!不同的应用场景,选择不同的技术
- 9楼riaware
- 然而.net core并没wcf
- Re: SunnyCase
- @riaware,有客户端
- 8楼刘标才
- 楼主直接放弃wcf吧,现在web都是用api,没人会再去用wcf了
- 7楼SunnyCase
- 说webapi比wcf强的 根本不懂两者应用场景的区别
- 6楼vbfool
- WCF又不是只能用来提供Web服务,NetTcp模式搞双工对于要求不高的项目也是个不错的通信框架,你们老来打击人家干嘛。,,还有那个让人转Java学Netty的,为什么不直接用DotNetty呢。
- 5楼小明同学
- 想学wcf这类通信协议,建议学java 开源的netty, 可以不学java web,只学这个很好找工作,大部分游戏公司都是用这个通信的。啥年代了,你还学wcf干啥,学了也找不到相关工作
- 4楼老左
- 我也喜欢用wcf
- Re: stonewl
- @老左,可以互相讨论哈
- 3楼掬一把月
- WCF是整合了原有的windows通讯的 .net Remoting,WebService,Socket的机制,并融合有HTTP和FTP的相关技术。,是Windows平台上开发分布式应用最佳的实践方式。,,是专门针对分布式的解决方案...
- 2楼小明同学
- .net 都快不行了,你还在研究wcf干啥,
- Re: JsppQ
- @小明同学,.net既然快不行了,你还泡这里干嘛?
- Re: stonewl
- @小明同学,哈哈!每个人都有自己发表观点的权利。你的说法我不反对,但是也说服不了我呀!等于说了句废话!
- 1楼农村小伙闯情关
- 研究webapi也比研究wcf强啊!
- Re: xuanbg
- @农村小伙闯情关,引用研究webapi也比研究wcf强啊!,,WCF同样可以实现RESTful的WEBAPI。,接口:,using System.ServiceModel;using System.ServiceModel.Web;using Insight.WS.Utils.Entity;namespace Insight.WS.Utils{ [ServiceContract] interface IAfs { /// lt;summarygt; /// 获取结构化地址 /// lt;/summarygt; /// lt;param name=quot;addressquot;gt;地址lt;/paramgt; /// lt;returnsgt;JsonResultlt;/returnsgt; [WebGet(UriTemplate = quot;openapi/regions/{addres