WCF - самое быстрое межпроцессное взаимодействие - PullRequest
8 голосов
/ 20 декабря 2010

A имеет доступную через Интернет (через basicHttpBinding) службу WCF, к которой я также хочу получить доступ из других .NET-сервисов на той же машине с как можно более высокой производительностью.Я понимаю, что netNamedPipeBinding идеально подходит для этого, но мне интересно, какая лучшая конфигурация будет предоставлена, что я только собираюсь общаться с другими процессами .NET.

Например, мне не обязательно использовать кодировку, такую ​​как SOAP, поскольку она, возможно, слишком громоздкая, и мне не нужна совместимость с любыми другими клиентами, кроме клиента .NET.Я также не думаю, что мне нужна какая-либо защита.

Какая конфигурация связывания будет наилучшей для этой цели (или любой другой конфигурации в этом отношении)

Ответы [ 3 ]

9 голосов
/ 20 декабря 2010

Как вы заметили, привязка NetNamedPipeBinding оптимизирована для связи на одном компьютере:

Обеспечивает безопасную и надежную привязку, оптимизированную для связи на компьютере.

Реф.: Системные привязки

В первой главе книги Ювала Лоуи "Программирование служб WCF" он предоставляет полезную диаграмму действий для принятия решений для выбора правильной привязки:

"Первый вопрос, который вы должны задать себе, заключается в том, нужно ли вашей службе взаимодействовать с клиентами, не являющимися WCF. Если ответ положительный, и если клиент является устаревшим клиентом MSMQ, выберите MsmqIntegrationBinding, который позволяет вашей службе взаимодействовать.через MSMQ с таким клиентом. Если вам нужно взаимодействовать с клиентом, отличным от WCF, и этот клиент ожидает базовый протокол веб-службы (веб-службы ASMX), выберите BasicHttpBinding, который отображает вашу службу WCF для внешнего мира, как если бы она былаВеб-служба ASMX (то есть базовый профиль WSI). Недостатком является то, что вы не можете использовать преимущества большинства современных протоколов WS- *. Однако, если клиент, не являющийся WCF, может понимать эти стандарты, выберите один из WSпривязки, такие как WSHttpBinding, WSFederationHttpBinding или WSDualHttpBinding.Если вы можете предположить, что клиент является клиентом WCF, но для этого требуется автономное или отключенное взаимодействие, выберите NetMsmqBinding, который использует MSMQ для транспортировки сообщений.Если клиент требует подключенного соединения, но может звонить через границы компьютера, выберите NetTcpBinding, который связывается по TCP.Если клиент находится на том же компьютере, что и служба, выберите NetNamedPipeBinding, который использует именованные каналы, чтобы максимизировать производительность.Вы можете настроить параметры привязки на основе дополнительных критериев, таких как необходимость обратных вызовов (WSDualHttpBinding) или федеративной безопасности (WSFederationHttpBinding). "

4 голосов
/ 20 декабря 2010

Конечно, именованный трубопроводный транспорт - лучший выбор.

Безопасность транспорта с EncryptAndSign включена по умолчанию на стандартном NetNamedPipeBinding. Вы, безусловно, хотите это убрать, поскольку это ускорит процесс без какого-либо реального влияния на безопасность по причинам, я обсуждаю здесь .

Я также подозреваю, но пока не подтвердил, что изменение элемента привязки кодировки сообщений может помочь. Это связано с тем, что по умолчанию используется собственная кодировка WCF «двоичное кодирование со встроенным словарем», которая представляет собой кодировку информационного набора XML, целью которого является сокращение избыточных байтов, например, в открытии и закрытии тегов элементов: достойная цель, когда задействован сетевой ввод-вывод, но может быть потрачена впустую нагрузка на процессор, когда передача сообщений полностью в памяти (при условии, что сообщения не слишком большие) Таким образом, переход на обычную кодировку текста также может повысить скорость.

1 голос
/ 24 ноября 2017

Я понимаю, что это довольно старый вопрос, но на него все же стоит ответить.Как уже упоминалось, именованные каналы являются самыми быстрыми, и вам необходимо отключить защиту, но наиболее существенный эффект вы получите, если избавитесь от сериализации контракта данных и переключитесь в режим потоковой передачи.

Используйте что-то вроде этого в качестве конфигурации привязки:

                new NetNamedPipeBinding
                {
                    MaxReceivedMessageSize     = 524288000,
                    ReceiveTimeout             = TimeSpan.MaxValue, // never timeout
                    SendTimeout                = TimeSpan.MaxValue, // never timeout
                    ReaderQuotas               =
                    {
                        MaxStringContentLength = 655360000
                    },
                    TransferMode               = TransferMode.Streamed,
                    Security = new NetNamedPipeSecurity
                    {
                        Mode = NetNamedPipeSecurityMode.None,
                        Transport = new NamedPipeTransportSecurity
                        {
                            ProtectionLevel = ProtectionLevel.None
                        }
                    }
                }

Определите ваши служебные сообщения следующим образом:

[MessageContract]
public class CallRequestMessage
{
    [MessageHeader]
    public string Arg1;
    [MessageHeader]
    public int ParametersLen;
    [MessageBodyMember]
    public Stream Parameters;
}

[MessageContract]
public class CallResponceMessage
{
    [MessageHeader]
    public int ResultCode;
    [MessageHeader]
    public int ResultsLen;
    [MessageBodyMember]
    public Stream Results;
}

[ServiceContract]
public interface ILocalServiceAPI
{
    [OperationContract]
    CallResponceMessage Call(CallRequestMessage message);
}

Недостатком этого метода является то, что теперь вам нужносериализуйте свои данные самостоятельно.Я предпочитаю использовать сериализацию protobuf напрямую MemoryStream.Поместите этот поток в свой CallRequestMessage.Parameters.

Не забудьте передать ParametersLen / ResultsLen в заголовке сообщения, так как Stream бесконечен (при чтении вы можете получить 0 байтов, но в отличие от обычных потоков вы должны продолжитьчтение).

...