Клиент CF WCF слишком долго переходит в открытое состояние (DuplexClientBase <T>.Open ()) - PullRequest
3 голосов
/ 28 июня 2011

У меня небольшая проблема с клиентом WCF.Во-первых, позвольте мне объяснить и дать вам подробности.

В настоящее время я занимаюсь разработкой системы, и я думал об отдельном основном приложении, потому что я разработал его для обновления с помощью dll.Поэтому я нашел MEF и начал много читать об этом.Но была проблема с MEF, он блокирует файл, без записи.Затем я нашел теневую копию.Итак, теперь я поместил клиента в другой домен приложения в основном приложении.Я читал, что обмен данными между доменами возможен через NET Remoting, поэтому я провел исследование и сделал это с 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());

Не стесняйтесь сообщать мне, если вам нужно что-то еще.

1 Ответ

0 голосов
/ 28 июня 2011

Вы осуществляете кросс-связь между доменами приложений в рамках одного процесса и используете WsHttpBinding?Ты понимаешь, насколько велики это накладные расходы?Это также значительно увеличивает сложность развертывания вашего приложения.Вероятно, это не источник вашей основной проблемы, но я бы начал с:

  • Замена WsDualHttpBinding на NetNamedPipeBinding

Для диагностики вашей проблемы начните с Трассировка WCF и проверка того, какая операция на клиенте и сервере занимает много времени - могут возникнуть проблемы с определением безопасности, поскольку в вашем параметре используется защита сообщений.

...