C#WCF客户端需要很长时间才能处于打开状态(DuplexClientBase<;T>;.Open())
本文关键字:lt DuplexClientBase Open gt 状态 于打开 客户端 长时间 C#WCF | 更新日期: 2023-09-27 18:00:43
我在WCF客户端上遇到了一个小问题。首先,请允许我向您解释并提供详细信息。
我目前正在开发一个系统,我正在考虑将主应用程序分开,因为我将其设计为使用dll进行更新。所以我找到了MEF,并开始阅读很多关于它的内容。但MEF有问题,它锁定了文件,无法写入。然后我找到了影子副本。因此,现在我将客户端放置在主应用程序的另一个AppDomain中。我读到通过NETRemoting可以实现跨域通信,所以我进行了研究并使用WCF进行了研究。
主应用程序是主机,它在新域中加载程序集并启动客户端。由于客户端是一个DLL,因此没有用于加载绑定、端点的AppConfig文件。我已经创建了一个类来帮助我,所以配置是通过程序添加的。
终于成功了!
但有一点我觉得不太好。在客户端,当执行DuplexClientBase.Open()指令时,需要20秒才能打开。我认为这是不好的,因为当我把客户端移到EXE(记住是一个DLL,配置是通过程序添加的)时,它不会花那么多时间。
也许配置中有问题,但我找不到。所以这里是souce代码文件。首先,当客户端位于控制台应用程序中时,这是App.config文件:
<configuration>
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="TcpBinding" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00" transactionFlow="false"
transferMode="Buffered" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" listenBacklog="10"
maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10"
maxReceivedMessageSize="65536">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Transport">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
<message clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
<wsDualHttpBinding>
<binding name="HttpBinding" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false"
transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00" />
<security mode="Message">
<message clientCredentialType="Windows" negotiateServiceCredential="true"
algorithmSuite="Default" />
</security>
</binding>
</wsDualHttpBinding>
</bindings>
<client>
<endpoint address="net.tcp://localhost:8080/ProtoServicio/EPServicioTcp"
binding="netTcpBinding" bindingConfiguration="TcpBinding"
contract="TestServicio.IServicio" name="TcpBinding">
<identity>
<userPrincipalName value="OlinzerLaptopV'Olinzer" />
</identity>
</endpoint>
<endpoint address="http://localhost:8081/ProtoServicio/EPServicioHttp"
binding="wsDualHttpBinding" bindingConfiguration="HttpBinding"
contract="TestServicio.IServicio" name="HttpBinding">
<identity>
<userPrincipalName value="OlinzerLaptopV'Olinzer" />
</identity>
</endpoint>
</client>
</system.serviceModel>
现在,这是创建绑定和端点的代码:
internal static Binding GetBinding()
{
WSDualHttpBinding binding = new WSDualHttpBinding();
TimeSpan span = new TimeSpan( 0, 1, 0 );
binding.Name = "HttpBinding";
binding.CloseTimeout = span;
binding.OpenTimeout = span;
binding.ReceiveTimeout = span;
binding.SendTimeout = span;
binding.BypassProxyOnLocal = false;
binding.TransactionFlow = false;
binding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
binding.MaxBufferPoolSize = 524288;
binding.MaxReceivedMessageSize = 65536;
binding.MessageEncoding = WSMessageEncoding.Text;
binding.TextEncoding = Encoding.UTF8;
binding.UseDefaultWebProxy = true;
binding.ReaderQuotas = new XmlDictionaryReaderQuotas();
binding.ReaderQuotas.MaxDepth = 32;
binding.ReaderQuotas.MaxStringContentLength = 8192;
binding.ReaderQuotas.MaxArrayLength = 16384;
binding.ReaderQuotas.MaxBytesPerRead = 4096;
binding.ReaderQuotas.MaxNameTableCharCount = 16384;
binding.ReliableSession = new ReliableSession();
binding.ReliableSession.Ordered = true;
binding.ReliableSession.InactivityTimeout = span;
binding.Security.Mode = WSDualHttpSecurityMode.Message;
binding.Security.Message.ClientCredentialType = MessageCredentialType.Windows;
binding.Security.Message.NegotiateServiceCredential = true;
binding.Security.Message.AlgorithmSuite = SecurityAlgorithmSuite.Default;
return binding;
}
代码创建的文件只包含Http端点。也许添加tcp端点会造成差异,但我不知道如何实现。上面的函数是由ClientClientBase类的构造函数调用的。
ServiceModel.DuplexClientBase<Servicio> MyClient = new ...<Servicio>(new InstanceContext(this), GetBinding(), GetEndpoint());
如果你还需要什么,随时通知我。
您在单个进程内进行跨AppDomain通信,而您使用的是WsHttpBinding
?你知道这有多大的开销吗?它还大大增加了应用程序部署的复杂性。这可能不是你主要问题的来源,但我会从开始
- 用
NetNamedPipeBinding
代替WsDualHttpBinding
若要诊断您的问题,请从WCF跟踪开始,并检查客户端和服务器上的哪个操作需要很长时间——由于您的设置使用了消息安全性,某些安全性解决可能会出现问题。