WCF - перезвонить клиенту (дуплекс?) - PullRequest
4 голосов
/ 29 апреля 2010

У меня проблема с тем, какое решение выбрать .. У меня работает сервер, на котором запущена служба, которая может принимать заказы с веб-сайта. К этому серверу подключено несколько клиентов (удаленных компьютеров).

Я бы очень хотел использовать WCF для общения, но не уверен, что это возможно.

Я не хочу настраивать все параметры брандмауэра клиента в своих маршрутизаторах, поэтому клиентам придется подключаться к серверу.

Но когда заказ получен на сервере, он должен быть передан конкретному клиенту.

Одним из решений может быть подключение клиента с использованием дуплексной привязки, но ему нужно каким-то образом поддерживать соединение, чтобы иметь возможность получать данные с сервера ... Это хороший способ сделать это ??

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

Любой может понять эту проблему.

Спасибо за любые советы: -)

С наилучшими пожеланиями Сорен Мюллер

Ответы [ 2 ]

5 голосов
/ 29 апреля 2010

Это именно то, для чего были созданы дуплексные привязки. Два лучших варианта: NetTcpBinding или PollingDuplexBinding .

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

Второй вариант, PollingDuplexBinding, включен в Silverlight SDK. Он использует инициированный клиентом «длинный» HTTP-запрос. Запрос ожидает сообщения, которые должны быть отправлены клиенту, и когда они приходят, клиентский запрос возвращается. Затем клиент инициирует новый HTTP-запрос обратно на сервер. Другими словами, у клиента всегда есть ожидающий HTTP-запрос. Это хорошо работает на брандмауэрах и должно использоваться, когда вы имеете дело с интернет-клиентами. Однако я обнаружил, что это не так быстро реагирует, как NetTcpBinding. Возможно, я что-то делал не так, но казалось, что попыткам отправить обратные вызовы на оставленные клиентские сеансы потребовалось время, чтобы «истекло время ожидания».

<Ч />

Вот пример файла конфигурации из моего недавнего проекта, который использовал NetTcpBinding для дуплексной связи. Обратите внимание, что помимо некоторых настроек для регулирования количества трафика я в значительной степени использую значения по умолчанию для этой привязки. Но есть всевозможные вещи , которые можно настроить, такие как receiveTimeout, inactivityTimeout и т. Д.

<configuration>
    <system.serviceModel>

        <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />

        <behaviors>
            <serviceBehaviors>
                <behavior name="">
                    <serviceMetadata httpGetEnabled="true" />
                    <serviceDebug includeExceptionDetailInFaults="true" />
                    <serviceThrottling maxConcurrentCalls="65535" 
                                       maxConcurrentSessions="65535" 
                                       maxConcurrentInstances="65535" />
                </behavior>
            </serviceBehaviors>
        </behaviors>

        <bindings>
            <netTcpBinding>
                <binding maxConnections="65535">
                    <security mode="None" />
                </binding>
            </netTcpBinding>
        </bindings>

        <services>
            <service name="BroadcastService">
                <endpoint address="" binding="netTcpBinding" contract="BroadcastService" />
            </service>
        </services>

    </system.serviceModel>
</configuration>
<ч />
[ServiceContract( CallbackContract = typeof( IBroadcastCallback ) )]
[ServiceBehavior( ConcurrencyMode = ConcurrencyMode.Multiple )]
public class BroadcastService : IDisposable
{

    [OperationContract(IsInitiating=true)]
    public long Subscribe( Guid clientID )
    {
        // clients call this to initiate the session
    }

    [OperationContract(IsOneWay = true)]
    public void Publish( BroadcastMessage message )
    {
        // client calls this to broadcast a message to
        // all other subscribed clients via callback
    }

}

[ServiceContract( Name = "BroadcastCallback" )]
public interface IBroadcastCallback
{

    [OperationContract( IsOneWay = true, AsyncPattern = true )]
    IAsyncResult BeginBroadcast(BroadcastMessage Message, AsyncCallback callback, object state);

    void EndBroadcast( IAsyncResult asyncResult );

}   // interface
0 голосов
/ 17 июня 2013

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

Служба WCF с привязкой wsDualhttp:
Этот подход хорош, если сервер и У клиента оба есть публичные IP-адреса. Клиент и сервер используют http для связи, поэтому нет ограничений брандмауэра. Но при инициализации дуплексной связи клиент должен установить отдельное соединение с сервером, чтобы у клиента также был публичный IP-адрес.

Служба WCF с привязкой NetTcp:
Этот подход использует протокол TCP для дуплексной связи, и этот способ можно использовать, если вы используете WCF. Единственный недостаток - некоторые брандмауэры блокируют порт TCP. В этом случае вам нужно исключение брандмауэра.

WCF NetHttpBinding с веб-сокетом:
этот подход использует протокол http, поэтому нет ограничений брандмауэра. При таком подходе клиент инициирует http-соединение, а затем обновляет до TCP-соединения для дуплексной связи. На данный момент только Win 8 или Win 2012 поддерживают веб-сокет WCF. Все серверы и клиенты - это wind 8 или win 2013, это путь.

Веб-сокет с использованием стороннего фреймворка (сигнал R, Xsocket.net):
Это не WCF, но все же вы можете реализовать остальные веб-службы или приложения-службы Windows. Использовать протокол HTTP, а затем обновить до TCP для дуплексной связи

...