Получение службы обратного вызова 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
...
Надеюсь, это поможет.