none
WCF Duplex Callback TimeOut Exception RRS feed

  • Question

  • I am working on WCF Duplex service.

    Have used the WsDualHTTPBinding for it. (instead of netTCPBinding) so as to support the Callbacks over the internet too.

    We have used  the "add service reference" mechanism for adding the proxy.

    But sometimes, we get the exception on Registering the callback to the DuplexService.

    Below is the snapshot of the WCF traces ,we received on investigating the Issue.

    All Firewalls are Opened for sending callback on Port 62000.

    But the strange thing i found in the Traces is the TimeOut exception for approx 1 minute in-spite of specifying the SendTimeOut,OpenTimeOut to 2 minutes on both client and WCF Service End.

    So... What is this TimeOut for , and if we can increase this timeOut?

    Below is my Sample configuration:

    <bindings> <wsDualHttpBinding> <binding name="wsDuplexConfiguration" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" openTimeout="00:02:00" closeTimeout="00:02:00" sendTimeout="00:02:00"> <reliableSession inactivityTimeout="00:10:00" /> <readerQuotas maxStringContentLength="2147483647" maxArrayLength="2147483647" /> </binding> </wsDualHttpBinding> <wsHttpBinding> <binding name="WSHttpBinding_IServiceDataService" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" sendTimeout="00:01:00"> <reliableSession inactivityTimeout="00:10:00" enabled="true" /> <readerQuotas maxStringContentLength="2147483647" maxArrayLength="2147483647" /> <!--Set the security mode to trnsport for deployment enviroments--><!-- <security>--> <security mode="TransportWithMessageCredential"> <transport proxyCredentialType="None" clientCredentialType="None" /> <message clientCredentialType="Certificate" /> </security> </binding> </wsHttpBinding> </bindings> <client>

    <endpoint address="https://domainName/ServiceInstance/ServiceDataService.svc/ws" behaviorConfiguration="CustomBehavior" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IServiceDataService"contract="Service.IServiceDataService" name="WSHttpBinding_IEZIADToolService">

            <identity>
              <dns value="domainName" />
            </identity>
          </endpoint>
          <endpoint address="http://domainName/ServiceInstance/ServiceDataSyncService.svc"
            binding="wsDualHttpBinding" bindingConfiguration="wsDuplexConfiguration"
            contract="DataSyncServiceReference.IServiceDataSyncService"
            name="wsDuplexConfiguration">
            <identity>
              <dns value="domainName" />
            </identity>
          </endpoint>
        </client>

    We invested much of hours on it..Please assist .

    Thanks in Advance !!!


    Wednesday, January 11, 2017 12:05 PM

All replies

  • Hi ankurastogi,

    >> in-spite of specifying the SendTimeOut,OpenTimeOut to 2 minutes on both client and WCF Service End.

    If so, it seems it is not related with TimeOut settings in WCF Service side. Does your service take long time to work?

    How did you set Port 62000? Did you set Inbound Rules in your client side by 62000?

    It would be helpful if you could share us your web.config in WCF Service side.

    Best Regards,

    Edward


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, January 12, 2017 5:51 AM
  • <?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --> <section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" /> <section name="exceptionHandling" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Configuration.ExceptionHandlingSettings, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" /> <section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" /> <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> </configSections> <!--<system.transactions> <defaultSettings timeout="00:05:00" /> </system.transactions>--> <connectionStrings configSource="Config\Connection.config" /> <loggingConfiguration configSource="Config\Logging.config" /> <exceptionHandling configSource="Config\ExceptionPolicies.config" /> <appSettings configSource="Config\App.config"></appSettings> <entityFramework> <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework"> <parameters> <parameter value="v12.0" /> </parameters> </defaultConnectionFactory> <providers> <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> <provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" /> </providers> </entityFramework> <system.web> <compilation debug="true" targetFramework="4.5" /> <httpRuntime targetFramework="4.5" executionTimeout="999999" maxRequestLength="2097151" /> </system.web> <system.serviceModel> <diagnostics performanceCounters="All"/> <client /> <extensions> <behaviorExtensions> <add name="EZIADToolServiceBehaviourExtension" type="EZI.ADTool.Aspects.Behaviors.CustomServiceBehaviourExtension,EZI.ADTool.Aspects"/> </behaviorExtensions> </extensions> <bindings> <basicHttpBinding> <binding name="serverapp" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" openTimeout="00:02:00" receiveTimeout="10:00:00" sendTimeout="00:02:00" closeTimeout="00:02:00"> <security mode="None"></security> </binding> </basicHttpBinding> <!--Currently in use Bindings Section Start--> <wsHttpBinding> <binding name="wserverapp" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" openTimeout="00:02:00" receiveTimeout="10:00:00" sendTimeout="00:02:00" closeTimeout="00:02:00"> <readerQuotas maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxDepth="2147483647" maxNameTableCharCount="2147483647" maxStringContentLength="2147483647"/> <!--<security mode="TransportWithMessageCredential">Should be used with IIS with SSL--> <security> <message clientCredentialType="Certificate" /> </security> <reliableSession enabled="true" inactivityTimeout="00:00:10" ordered="True" /> </binding> </wsHttpBinding> <wsDualHttpBinding> <binding name="wsDuplexConfiguration" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" openTimeout="00:02:00" receiveTimeout="10:00:00" sendTimeout="00:02:00" closeTimeout="00:02:00"> <readerQuotas maxStringContentLength="2147483647" maxArrayLength="2147483647"/> <reliableSession inactivityTimeout="04:00:00" /> </binding> </wsDualHttpBinding> <!--Currently in use Bindings Section End--> <customBinding> <binding name="testBinding" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00"> <webMessageEncoding webContentTypeMapperType="EZI.ADTool.Aspects.Utils.JsonContentMapper, EZI.ADTool.Aspects" /> <httpTransport manualAddressing="true" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" /> </binding> </customBinding> <webHttpBinding> <binding name="poxwebBinding" maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" /> <binding name="jsonwebBinding" receiveTimeout="00:10:00" maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" /> </webHttpBinding> </bindings> <behaviors> <endpointBehaviors> <behavior name="poxBehavior"> <webHttp helpEnabled="true" defaultBodyStyle="Bare" defaultOutgoingResponseFormat="Xml" /> </behavior> <behavior name="jsonBehavior"> <webHttp helpEnabled="true" defaultBodyStyle="Bare" defaultOutgoingResponseFormat="Json" automaticFormatSelectionEnabled="true" /> </behavior> <behavior name="web"> <webHttp /> </behavior> </endpointBehaviors> <serviceBehaviors > <behavior name="EZIADToolServiceBehavior"> <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/> <serviceDebug includeExceptionDetailInFaults="true" /> <dataContractSerializer maxItemsInObjectGraph="2147483647" /> <serviceSecurityAudit suppressAuditFailure="false" serviceAuthorizationAuditLevel="Failure" messageAuthenticationAuditLevel="Failure" auditLogLocation="Application" /> <serviceCredentials> <clientCertificate> <authentication certificateValidationMode="ChainTrust" revocationMode="NoCheck"/> </clientCertificate> <!--<serviceCertificate findValue="dev.om.egonzehnder.com" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/>--> <!--<serviceCertificate findValue="BD3D1A77690CF4E9038F71CD7FC955A3E63E9D77" storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint"/>--> <serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindByIssuerName"/> </serviceCredentials> <EZIADToolServiceBehaviourExtension /> </behavior> <behavior name="MASServiceBehavior"> <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="true" /> <dataContractSerializer maxItemsInObjectGraph="2147483647" /> </behavior> <behavior name="MASBusinessBehavior"> <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="true" /> <dataContractSerializer maxItemsInObjectGraph="2147483647" /> </behavior> <behavior name="EZIADToolDataSyncServiceBehavior"> <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="true" /> <dataContractSerializer maxItemsInObjectGraph="2147483647" /> </behavior> </serviceBehaviors> </behaviors> <services> <service behaviorConfiguration="EZIADToolServiceBehavior" name="EZI.ADTool.ServiceApp.Core.EZIADToolService"> <endpoint address="" behaviorConfiguration="web" binding="webHttpBinding" bindingConfiguration="poxwebBinding" contract="EZI.ADTool.ServiceApp.IEZIADToolService" /> <endpoint address="json" behaviorConfiguration="jsonBehavior" binding="customBinding" bindingConfiguration="testBinding" contract="EZI.ADTool.ServiceApp.IEZIADToolService" /> <!--<endpoint address="web" binding="basicHttpBinding" contract="EZI.ADTool.ServiceApp.IEZIADToolService"/>--> <endpoint address="ws" binding="wsHttpBinding" bindingConfiguration="wserverapp" contract="EZI.ADTool.ServiceApp.IEZIADToolService" > <identity> <dns value="**server**"/> </identity> </endpoint> </service> <service name="EZI.ADTool.ServiceApp.Core.EZIADToolDataSyncService" behaviorConfiguration="EZIADToolDataSyncServiceBehavior"> <endpoint binding="wsDualHttpBinding" bindingConfiguration="wsDuplexConfiguration" name="wsDuplexConfiguration" contract="EZI.ADTool.ServiceApp.IEZIADToolDataSyncService"/> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> <host> <baseAddresses> <add baseAddress="http://hostname/EZIADToolDataSyncService.svc" /> </baseAddresses> </host> </service> </services> <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" minFreeMemoryPercentageToActivateService="0" /> </system.serviceModel> <system.webServer> <modules runAllManagedModulesForAllRequests="true" /> <!-- To browse web app root directory during debugging, set the value below to true. Set to false before deployment to avoid disclosing web app folder information. --> <security> <requestFiltering> <requestLimits maxAllowedContentLength="2000000000" /> </requestFiltering> </security> <directoryBrowse enabled="true" /> </system.webServer> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <!--<dependentAssembly> <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" /> </dependentAssembly>--> </assemblyBinding> <gcAllowVeryLargeObjects enabled="true" /> </runtime> <system.data> <DbProviderFactories> <remove invariant="System.Data.SQLite.EF6" /> <add name="SQLite Data Provider (Entity Framework 6)" invariant="System.Data.SQLite.EF6" description=".NET Framework Data Provider for SQLite (Entity Framework 6)" type="System.Data.SQLite.EF6.SQLiteProviderFactory, System.Data.SQLite.EF6" /> </DbProviderFactories> </system.data> </configuration>

    Hello Edward,

    Above is my Web.config

    Below is the code for setting the clientBaseAddress:

     private static bool CheckAndCreateChannel(int projectsID)
            {
                bool retVal = true;
                //MessageBox.Show("Test Data");
                Logger.LogMessage(LogLevelL4N.WARNING, "Duplex Checking Service Status");
                // lock the object for resolving concurrency issues
                lock (typeof(DataSyncServiceConsumer))
                {
                    try
                    {
    
                        if (eziADToolDataSyncServiceClient == null 
                           || (eziADToolDataSyncServiceClient.InnerDuplexChannel != null && (eziADToolDataSyncServiceClient.InnerDuplexChannel.State == System.ServiceModel.CommunicationState.Faulted || eziADToolDataSyncServiceClient.InnerDuplexChannel.State == System.ServiceModel.CommunicationState.Closed)) 
                           || (eziADToolDataSyncServiceClient.InnerChannel != null && (eziADToolDataSyncServiceClient.InnerChannel.State == System.ServiceModel.CommunicationState.Faulted || eziADToolDataSyncServiceClient.InnerChannel.State == System.ServiceModel.CommunicationState.Closed))) 
                        {
                            if(eziADToolDataSyncServiceClient!=null && eziADToolDataSyncServiceClient.InnerDuplexChannel!=null)
                            {
                                Logger.LogMessage(LogLevelL4N.FATAL, "Duplex Channel recreation initiated with the duplex channel state:" + eziADToolDataSyncServiceClient.InnerDuplexChannel.State.ToString());
                            }
                            InstanceContext callBackInstanceContext = new InstanceContext(new DataCallBackHandler());
                            Logger.LogMessage(LogLevelL4N.FATAL, "Service new Callback channel established");
                            eziADToolDataSyncServiceClient = new EZIADToolDataSyncServiceClient(callBackInstanceContext);
                            if (CreateChannel(projectsID))
                            {
                                Logger.LogMessage(LogLevelL4N.FATAL, "Establishing the events for the channel fault and closed");
                                ((ICommunicationObject)eziADToolDataSyncServiceClient).Faulted += DataSyncServiceConsumer_Faulted;
                                //((ICommunicationObject)eziADToolDataSyncServiceClient).Closed += DataSyncServiceConsumer_Closed;
                            }
                            else
                            {
                                retVal = false;
                                Logger.LogMessage(LogLevelL4N.FATAL, "Channel couldn't established for the duplex service.");
                            }
                        }
                        else
                        {
                            Logger.LogMessage(LogLevelL4N.FATAL, "Channel is already established, no recreation needed.");
                        }
                    }
                    catch (Exception ex)
                    {
                        // Log if we cannot register
                        string message = "An error occured while creating the callback channel while duplex service.";
                        Logger.LogMessage(LogLevelL4N.FATAL, message);
                        Logger.LogException(ex);
                        message = EZI.ADTool.UI.Infrastructure.Util.Common.HandleException(ex, message, Log4netLogger.LogLevelL4N.FATAL);
                        //MessageBox.Show(message, "Calibration Sheet", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        retVal = false;
                    }
                }
    
                return retVal;
            }
    
    
    
            static bool CreateChannel(int projectID)
            {
                bool retVAl = false;
                //MessageBox.Show("Create channel invoked");
                // lock the object for resolving concurrency issues
                try
                {
                    // check if the channel is not in faulted or closed state
                    if (eziADToolDataSyncServiceClient != null)
                    {
    
                        WSDualHttpBinding binding = (WSDualHttpBinding)eziADToolDataSyncServiceClient.Endpoint.Binding; // fetch the binding configurations from the service client
                        if (binding != null)
                        {
                            //string callBackPort = Utils.UtilityMethods.GetAppSettings(Utils.ConfigKeys.CallbackChannelPort);
    
                            // Get the Duplex callback Port
                            int? duplexCallbackPort = SQLiteDBManager.FetchDuplexServiceCallbackChannelPort(SQLiteDBManager.GetClSheetDBConnection(), projectID);
    
                            // if duplex port is null, set the callbackPort to empty
                            string callBackPort = duplexCallbackPort == null || duplexCallbackPort == 0 ? "" : duplexCallbackPort.ToString();
    
                            //MessageBox.Show( callBackPort + " Callback Port");
    
                            if (!string.IsNullOrWhiteSpace(callBackPort))
                            {
                                // get the system's host name (machine name)
                                string hostname = Dns.GetHostName();
    
                                if (!string.IsNullOrWhiteSpace(hostname))
                                {
                                    // set the client base address
                                    string clientCallbackAddress = "http://" + hostname + ":" + callBackPort + "/ADToolService";
                                    clientCallbackAddress += Guid.NewGuid().ToString();
                                    binding.ClientBaseAddress = new Uri(clientCallbackAddress);
                                    Logger.LogMessage(LogLevelL4N.FATAL, "New Callback channel established for the client with machine name" + hostname + ", with the address " + clientCallbackAddress);
                                    //MessageBox.Show("New Callback channel established for the client with machine name" + hostname + ", with the address " + clientCallbackAddress);
                                    retVAl = true;
                                }
                                else
                                {
                                    Logger.LogMessage(LogLevelL4N.FATAL, "Duplex Callback Channel Hostname is NULL, channel creation will fail");
                                }
                            }
                            else
                            {
                                Logger.LogMessage(LogLevelL4N.FATAL, "Duplex Callback Channel Port is NULL, channel creation will fail");
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
    
                    // Log if we cannot register
                    string message = "Cannot create callback channel for the duplex services.";
                    Logger.LogMessage(LogLevelL4N.FATAL, message);
                    Logger.LogException(ex);
                    message = EZI.ADTool.UI.Infrastructure.Util.Common.HandleException(ex, message, Log4netLogger.LogLevelL4N.FATAL);
                    //MessageBox.Show(message, "Calibration Sheet", MessageBoxButtons.OK, MessageBoxIcon.Information);
    
                }
    
                return retVAl;
    
            }

    No Edward, we didn't set any specific inbound rules for the 62000..

    and it's happening mostly at the first time when we register to duplex srevice.

    Note: we are Registering to the Duplex service from ADDIN we have created for excel.

    Thanks in advance !!!

    Any help really appreciated...

    Regards,

    Hemant


    • Edited by ankurastogi Thursday, January 12, 2017 2:14 PM
    Thursday, January 12, 2017 2:07 PM
  • Hi ankurastogi,

    >> All Firewalls are Opened for sending callback on Port 62000.

    >> we didn't set any specific inbound rules for the 62000..

    What do you mean by these? Are your WCF Service and client in the same computer or different computers? If you are in different computers, I suggest you create new Inbound Rules in firewall for 62000 in client side or just disable firewall to make a test.

    Is the WCF trace in server side or client side? I suggest you enable tracing in both side, and then check the errors.

    Best Regards,

    Edward


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, January 13, 2017 4:52 AM
  • Hi Ankurastogi,

    WSDualhttpbinding will not work on internet. I will work for intranet. 

    For above issue you need to right the registering callback to duplex service logic into try catch block . in catch block just recall the logic again (upto one level), it will work on intranet.

    WSDualHttpBinding will not work on internet because server response as client and client respond as a server on callback channel, client machine does not have public IP so it giving error in handshaking.

    Thanks & Regards

    Pardeep 

     


    Wednesday, February 1, 2017 9:19 AM
  • WSDualHttpBinding will work if both server and client have public IP.
    Wednesday, February 1, 2017 9:21 AM
  • Thanks for your reply and suggestions.....

    Can we use SignalR for the above scenariao, so as to work it seamlessly over the internet and intranet?

    What are the various implications and impacts on using SignalR for bidirectional communication?

    For proposing this solution to the team, we may be needing the list of big gaints who are using the SignalR technology? Can you help us in naming some of them?

    Any help would be thankful !!!

    Friday, March 24, 2017 7:50 AM