WCF使用问题小结
1、“套接字终止的问题”:必然是连接问题,但是引发的情况很多,并且提示就这么一个,很模糊
a、WCF调用之后连接是要关闭的client.Close(),该方法是很有必要的,否则,每次调用方法就会新建一个连接,当TCP连接过多的时候就可能发生这个错误;这个close其实并非真正的关闭连接,会闲置下来,如果该应用继续调用之前的服务,还会使用这个链接。注意关闭方法不用使用异步关闭,否则会引发其他问题,并且这个关闭并不耗什么资源、性能
b、svclog中的该错误提示可以忽略,因为IIS的限制,默认的连接超时时间为2分钟,IIS里面可以设置,不过本人设置好像不起作用,暂时没找到方法;日志记录的错误,并不会影响使用,属于正常情况
2、“没有可用的套接字资源”:同1、a是一样的,只要有正常关闭的方法即可
3、“在流的位置 1 处读取消息组帧格式时出错(状态: Start) ”:先吐槽一下,就因为这个偶发性的小问题,导致我查了好多天,换了HTTP连接方式,出现超时问题,最后再换回来,折腾好多天,发生原因很简单:应用程序池设置的回收时间为3分钟,默认为29个小时吧。后来修改为固定时间回收之后,WCF正常、稳定,当然又改回了TCP连接的方式
总结:基本上都是在套接字终止那折腾。
其他:分享一些WCF中常用的工具或者是监控方法
1、监控连接数cmd:netstat -ano | find ":808";该命令用于监视当前活动的808端口,引号中的关键字可以随意修改,相当于全模糊查询,也可以通过“任务管理器--性能--资源监视器--网络--TCP连接”观察
2、查找PID: 1、cd C:\Windows\System32\inetsrv 2、appcmd list wp;IIS7.5中查找应用程序池对应的PID,需要以管理员身份运行
3、svclog日志,配置如下,可以使用SvcTraceViewer.exe打开
1 <!--记录错误日志--> 2 <system.diagnostics> 3 <sources> 4 <source name="System.ServiceModel" switchValue="Warning" propagateActivity="true"> 5 <listeners> 6 <add name="xml" /> 7 </listeners> 8 </source> 9 </sources> 10 <sharedListeners> 11 <add name="xml" type="System.Diagnostics.XmlWriterTraceListener" initializeData="d:\temp\wcf.svclog" /> 12 </sharedListeners> 13 </system.diagnostics>
4、我的一些核心配置方法,同时把http的方式和net.tcp的方式都写上,通过httpGetEnabled控制是否启用http的调用方式,元数据的根节点使用跟net.tcp一样的配置,这样做的话就可以设置连接数,否则连接数的数值无法超过10
1 <system.serviceModel> 2 3 <serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> 4 5 <services> 6 <service behaviorConfiguration="TcpBehavior" name="PromotionService"> 7 <endpoint address="" binding="netTcpBinding" bindingConfiguration="BindingForTcp" contract="IPromotionService" /> 8 <endpoint address="mex" binding="netTcpBinding" bindingConfiguration="BindingForTcp" contract="IMetadataExchange" /> 9 <endpoint address="" binding="basicHttpBinding" bindingConfiguration="BindingForHttp" contract="IPromotionService" /> 10 </service> 11 </services> 12 13 <bindings> 14 <!--TCP绑定--> 15 <netTcpBinding> 16 <binding name="BindingForTcp" maxConnections="10000" listenBacklog="1000" maxReceivedMessageSize="2147483647" receiveTimeout="00:30:30" maxBufferPoolSize="2147483647" maxBufferSize="2147483647"> 17 <security mode="None"> 18 <transport clientCredentialType="Windows" /> 19 <message clientCredentialType="Windows" /> 20 </security> 21 </binding> 22 </netTcpBinding> 23 24 <basicHttpBinding> 25 <binding name="BindingForHttp" maxReceivedMessageSize="2147483647" receiveTimeout="00:30:30"/> 26 </basicHttpBinding> 27 </bindings> 28 29 <behaviors> 30 <serviceBehaviors> 31 <behavior name="TcpBehavior"> 32 <!-- 为避免泄漏元数据信息,请在部署前将以下值设置为 false 并删除上面的元数据终结点 --> 33 <serviceMetadata httpGetEnabled="false"/> 34 <!-- 要接收故障异常详细信息以进行调试,请将以下值设置为 true。在部署前设置为 false 以避免泄漏异常信息 --> 35 <serviceDebug includeExceptionDetailInFaults="true"/> 36 <serviceTimeouts transactionTimeout="00:03:00" /> 37 <serviceThrottling maxConcurrentCalls="1000" maxConcurrentInstances="1000" maxConcurrentSessions="1000" /> 38 <dataContractSerializer maxItemsInObjectGraph="2147483647" /> 39 </behavior> 40 </serviceBehaviors> 41 </behaviors> 42 43 44 <client> 45 <endpoint address="net.tcp://.../QueryService.svc" 46 binding="netTcpBinding" bindingConfiguration="BindingForTcp" 47 contract="GoodsQueryService.IQueryService" name="NetTcpBinding_IQueryService" /> 48 </client> 49 </system.serviceModel>
5、WCF关闭方法,封装的3种关闭方法
1 /// <summary> 2 /// Wcf调用后自动关闭(无返回值) 3 /// </summary> 4 /// <typeparam name="T"></typeparam> 5 /// <param name="client"></param> 6 /// <param name="work"></param> 7 public static void Using<T>(this T client, Action<T> work) where T : ICommunicationObject 8 { 9 try 10 { 11 work(client); 12 client.Close(); 13 } 14 catch (CommunicationException e) 15 { 16 client.Abort(); 17 } 18 catch (TimeoutException e) 19 { 20 client.Abort(); 21 } 22 catch (Exception e) 23 { 24 client.Abort(); 25 throw; 26 } 27 } 28 29 30 /// <summary> 31 /// Wcf调用后自动关闭(有返回值) 32 /// </summary> 33 /// <typeparam name="T"></typeparam> 34 /// <typeparam name="TResult"></typeparam> 35 /// <param name="client"></param> 36 /// <param name="work"></param> 37 /// <returns></returns> 38 public static TResult Using<T, TResult>(this T client, Func<T, TResult> work) where T : ICommunicationObject 39 { 40 try 41 { 42 var result = work(client); 43 44 client.Close(); 45 46 return result; 47 } 48 catch (Exception e) 49 { 50 client.Abort(); 51 52 throw; 53 } 54 } 55 56 public static void WcfClientClose<T>(ClientBase<T> client) where T : class 57 { 58 try 59 { 60 client.Close(); 61 } 62 catch 63 { 64 client.Abort(); 65 } 66 }