繁体   English   中英

C# WCF 客户端打开时间过长 state (DuplexClientBase<t> 。打开())</t>

[英]C# WCF Client takes too long to opened state (DuplexClientBase<T>.Open())

我在使用 WCF 客户端时遇到了一点问题。 首先,请允许我向您解释并提供详细信息。

我目前正在开发一个系统,我正在考虑单独的主应用程序,因为我将它设计为使用 dll 进行更新。 所以我找到了 MEF,并开始大量阅读它。 但是MEF有问题,它锁定了文件,没有写入。 然后我找到了影子副本。 所以现在我将客户端放在主应用程序的另一个 AppDomain 中。 我已经读过可以通过 NET Remoting 进行跨域通信,因此我进行了研究并使用 WCF 完成了它。

主应用程序是主机,它将程序集加载到新域中并启动客户端。 由于客户端是 DLL,因此没有 AppConfig 文件来加载绑定、端点。 我创建了一个 class 来帮助我,所以配置是以编程方式添加的。

最后,它起作用了!

但是有一点我觉得不太好。 在客户端,当指令 DuplexClientBase.Open() 被执行时,需要 20 秒才能打开。 我认为这不好,因为当我将客户端移动到 EXE 时(记住是 DLL 并且配置是通过编程方式添加的)它并不需要所有时间。

也许是配置中有问题,但我找不到。 所以这里是源代码文件。 首先,这是 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 Endpoint。 也许添加 tcp 端点可能会有所不同,但是,我不知道如何做到这一点。 上面的function是由ClientClientBase class的构造函数调用的。

ServiceModel.DuplexClientBase<Servicio> MyClient = new ...<Servicio>(new InstanceContext(this), GetBinding(), GetEndpoint());

如果您需要其他任何东西,请随时通知我。

您正在单个进程中进行跨 AppDomain 通信并且正在使用WsHttpBinding 你知道这有多大的开销吗? 它还极大地增加了应用程序部署的复杂性。 它可能不是您的主要问题的根源,但我将从:

  • NetNamedPipeBinding替换WsDualHttpBinding

要诊断您的问题,请从WCF 跟踪开始,并检查客户端和服务器上的哪些操作需要很长时间 - 由于您的设置使用消息安全性,因此某些安全性解决可能会出现问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM