[英]C# WCF Client takes too long to opened state (DuplexClientBase<T>.Open())
I'm having a little problem with a WCF client.我在使用 WCF 客户端时遇到了一点问题。 First, allow me to explain and give you details.首先,请允许我向您解释并提供详细信息。
I'm currently developing a system, and I was thinking in separate the main application because I designed it to be updated with dlls.我目前正在开发一个系统,我正在考虑单独的主应用程序,因为我将它设计为使用 dll 进行更新。 So I found MEF, and began to read a lot about it.所以我找到了 MEF,并开始大量阅读它。 But there was problem with MEF, it locks the file, no write.但是MEF有问题,它锁定了文件,没有写入。 Then I found shadow copy.然后我找到了影子副本。 So now I placed the client in another AppDomain in the main Application.所以现在我将客户端放在主应用程序的另一个 AppDomain 中。 I've read that communication cross domains is possible through NET Remoting, so I made research and done it with WCF.我已经读过可以通过 NET Remoting 进行跨域通信,因此我进行了研究并使用 WCF 完成了它。
The main Application is the host, it loads the assembly in a new domain and starts the client.主应用程序是主机,它将程序集加载到新域中并启动客户端。 As the client is a DLL, there is no AppConfig file to load bindings, endpoints.由于客户端是 DLL,因此没有 AppConfig 文件来加载绑定、端点。 I've created a class that helps me with that, so the config is added programatically.我创建了一个 class 来帮助我,所以配置是以编程方式添加的。
Finally, it works!最后,它起作用了!
But there is a little thing I don't think is ok.但是有一点我觉得不太好。 In the client, when the instruction DuplexClientBase.Open() is executed, it takes 20 seconds to open.在客户端,当指令 DuplexClientBase.Open() 被执行时,需要 20 秒才能打开。 I think is not OK 'cause when I move the client to a EXE (remember is a DLL and the config is added programatically) it doesn't take all that time.我认为这不好,因为当我将客户端移动到 EXE 时(记住是 DLL 并且配置是通过编程方式添加的)它并不需要所有时间。
Maybe is something wrong in the config, but I can't find it.也许是配置中有问题,但我找不到。 So here are the souce code files.所以这里是源代码文件。 First, this is the App.config file, when the client is in a console application:首先,这是 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>
And now, this is the code that creates the binding and endpoint:现在,这是创建绑定和端点的代码:
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;
}
The file created by the code only contains the Http Endpoint.代码创建的文件仅包含 Http Endpoint。 Maybe adding the tcp endpoint could make the diference, but, I have no idea how to make it.也许添加 tcp 端点可能会有所不同,但是,我不知道如何做到这一点。 The function above is called by the constructor of the ClientClientBase class.上面的function是由ClientClientBase class的构造函数调用的。
ServiceModel.DuplexClientBase<Servicio> MyClient = new ...<Servicio>(new InstanceContext(this), GetBinding(), GetEndpoint());
Feel free to notify me if you need anything else.如果您需要其他任何东西,请随时通知我。
You are doing cross AppDomain communication within single process and you are using WsHttpBinding
?您正在单个进程中进行跨 AppDomain 通信并且正在使用WsHttpBinding
? Do you understand how big overhead this has?你知道这有多大的开销吗? It also highly increases complexity of your application deployment.它还极大地增加了应用程序部署的复杂性。 It is probably not source of your main problem but I would start with:它可能不是您的主要问题的根源,但我将从:
WsDualHttpBinding
with NetNamedPipeBinding
用NetNamedPipeBinding
替换WsDualHttpBinding
To diagnosing your issue start with WCF tracing and check which operation on both client and server takes a long time - there can be problem with some security resolving because your setting uses message security.要诊断您的问题,请从WCF 跟踪开始,并检查客户端和服务器上的哪些操作需要很长时间 - 由于您的设置使用消息安全性,因此某些安全性解决可能会出现问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.