Получение службы обратного вызова WCF из веб-приложения ASP.NET, размещенного в IIS

Я работаю над этим вопросом уже пару дней.

Проблема состоит из 3 рабочих частей. У меня есть сайт ASP.NET, служба WCF IIS и приложение WPF xbap.

Я пытаюсь передать переменные с сайта ASP.NET в приложение WPF xbap. Поэтому я настроил службу WCF с помощью wsDualHttpBinding и использовал обратные вызовы для уведомления ASP.NET и xbap.

Теперь, когда я размещаю службу WCF в IIS 6 на нашем сервере и запускаю хостинг ASP.NET в VS2012, iisexpress локально и xbap локально. Работает нормально. Но как только я публикую сайт ASP.NET на IIS 6 на нашем сервере, приложение ASP.NET никогда не получит обратный вызов. Оба находятся в пуле приложений.

Есть ли настройка или что-то, что мне нужно, чтобы ASP.NET оставался открытым портом прослушивания для обратных вызовов? XBAP все еще получает обратные вызовы, нет проблем.

Конфигурация службы выглядит следующим образом: (обратите внимание, я максимально увеличил буферы из-за простоты, чтобы исключить это)

<configuration>
  <system.diagnostics>
    <sources>
      <source propagateActivity="true" name="System.ServiceModel" switchValue="Warning,ActivityTracing">
        <listeners>
          <add type="System.Diagnostics.DefaultTraceListener" name="Default">
            <filter type="" />
          </add>
          <add name="ServiceModelTraceListener">
            <filter type="" />
          </add>
        </listeners>
      </source>
    </sources>
    <sharedListeners>
       <add initializeData="web_tracelog.svclog" type="System.Diagnostics.XmlWriterTraceListener, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
    name="ServiceModelTraceListener" traceOutputOptions="Timestamp">
        <filter type="" />
      </add>
    </sharedListeners>
  </system.diagnostics>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <bindings>
     <wsDualHttpBinding>
        <binding receiveTimeout="00:01:00" sendTimeout="00:00:05" maxReceivedMessageSize="2147483647"
      messageEncoding="Text" textEncoding="utf-8">
          <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
        maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
          <security mode="None" />
        </binding>
      </wsDualHttpBinding>
    </bindings>
    <behaviors>      
      <serviceBehaviors>
        <behavior>
         <serviceMetadata httpGetEnabled="true"/>
         <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="false"
  multipleSiteBindingsEnabled="false" />
    <protocolMapping>
      <add scheme="http" binding="wsDualHttpBinding" />
    </protocolMapping>
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <directoryBrowse enabled="true"/>
   </system.webServer>
</configuration>

У сервиса есть методы, где клиенты будут подписываться на списки ответных звонков. Затем методы будут увеличиваться по списку для отправки вызова обратного вызова.

[ServiceContract(CallbackContract = typeof(IClientCallback))]
public interface IVisualisationService
{
    [OperationContract(IsOneWay = true)]
    void SubscribeToRedenderHoles(string address);

    [OperationContract(IsOneWay = true)]
    void SubscribeToEditSelectedHoles(string address);

    [OperationContract(IsOneWay = true)]
    void SubscribeToShowHoles(string address);

    [OperationContract(IsOneWay = true)]
    void RedenderHoles(Hole3D[] holes, string address, int channelhashcode);

    [OperationContract(IsOneWay = true)]
    void EditSelectedHoles(Guid[] holesIds, string address);

    [OperationContract(IsOneWay = true)]
    void ShowHoles(string address);


}

public interface IClientCallback
{
    [OperationContract(IsOneWay = true)]
    void OnRenderHoles(Hole3D[] holes);

    [OperationContract(IsOneWay = true)]
    void OnEditSelectedHoles(Guid[] holesIds);

    [OperationContract(IsOneWay = true)]
    void OnShowHoles(int channelhashcode);
}

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

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class VisualisationService : IVisualisationService
{

Теперь для клиента ASP.NET web.config

<system.serviceModel>
    <bindings>
        <wsDualHttpBinding>
            <binding name="WSDualHttpBinding_IVisualisationService" maxReceivedMessageSize="2147483647" messageEncoding="Text" textEncoding="utf-8" >
              <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
              <security mode="None" />
            </binding>
        </wsDualHttpBinding>
    </bindings>
    <client>
        <endpoint address="http://hims.mecha.com/VisualisationWcfService/VisualisationService.svc"
            binding="wsDualHttpBinding" bindingConfiguration="WSDualHttpBinding_IVisualisationService"
            contract="VisualisationServiceReference.IVisualisationService"
            name="WSDualHttpBinding_IVisualisationService" />
    </client>
</system.serviceModel>

Затем клиент приложения XBAP app.config

<configuration>
    <system.serviceModel>
        <bindings>
            <wsDualHttpBinding>
                <binding name="WSDualHttpBinding_IVisualisationService"     maxReceivedMessageSize="2147483647" messageEncoding="Text" textEncoding="utf-8" >
              <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>

                    <security mode="None" />
                </binding>
            </wsDualHttpBinding>
        </bindings>
        <client>
          <endpoint address="http://hims.mecha.com/VisualisationWcfService/VisualisationService.svc"        
            binding="wsDualHttpBinding" bindingConfiguration="WSDualHttpBinding_IVisualisationService"
            contract="VisualisationService.IVisualisationService" name="WSDualHttpBinding_IVisualisationService" />
        </client>
    </system.serviceModel>
</configuration>

В обоих клиентах я использовал метод Add Service Reference, чтобы добавить WCF в проекты ASP.NET и XBAP. Я настроил обоих клиентов, чтобы иметь код и, конечно, обрабатывать методы для каждого обратного вызова.

sealed class VisualisationManager : VisualisationService.IVisualisationServiceCallback

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

1 ответ

Поздний ответ, но в случае, если кто-то, как я, дойдет до этого вопроса через Большой Г.

У меня была похожая проблема, и решение для меня состоит в том, чтобы добавить CallbackBehavior к классу, который реализует интерфейс обратного вызова (в вашем случае; IClientCallback). как это:

[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, UseSynchronizationContext = false)]
public class ClientCallback : IClientCallback
...

Надеюсь, это поможет.

Другие вопросы по тегам