2010-04-29 2 views
3

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

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

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

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

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

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

Кто-нибудь есть понимание этой проблемы.

Thx много для любого посоветуйте :-)

С наилучшими пожеланиями Сорен Müller

+1

Будьте осторожны, сохраняя сеансы в ферме и такие вещи, как перезагрузка. –

ответ

4

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

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

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


Вот пример конфигурационного файла из моего недавнего проекта, который использовал NetTcpBinding для дуплексной связи. Обратите внимание, что, помимо некоторых настроек для обслуживания дросселирования, я в значительной степени использую значения по умолчанию для этой привязки. Но there's all kinds of things вы можете настроить такие как 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

Ahh звучит хорошо ... Это через Интернет, и, кажется, я думаю, что TCPBinding лучше всего звучит. Но для того, чтобы сервер отправил данные клиенту Async, соединение должно поддерживаться клиентом. Есть ли какие-либо настройки привязки для выполнения трюка или вам нужно послать сообщение «сердцебиение», на сервер, чтобы сохранить его в живых.? У вас есть какой-нибудь пример App.config о том, как настроить хороший TCPBinding для этого? Thx .. :-) –

+0

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

+0

Я тоже в такой ситуации, и я уже использую привязку nettcp с дуплексной связью. но моя проблема заключается в том, что число подключений достигает 800 клиентов, которые перестают отвечать на запросы и бросают «Открытая операция не завершилась в течение отведенного времени ожидания 00:01:00. Время, выделенное этой операции, возможно, было частью более длительного таймаута. " IE: Я использую цикл для создания соединения с сервером WCF. Цените свою помощь по этой проблеме. – Mahesh

0

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

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

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

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

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

Смежные вопросы