HTTP 503 Error When Hosting WCF from a Worker Role

Answered HTTP 503 Error When Hosting WCF from a Worker Role

  • Thursday, December 16, 2010 10:34 AM
     
      Has Code

    I have a WCF service using wsHttpBinding. I would like to host it from a Worker Role on Azure at 8008 port. I deployed the project and then visit the URL http://mysvc.cloudapp.net:8080/EchoService but got a HTTP 503 error without any additional information and exception.

    I had added an endpoint in my Azure Project as Input, http, 8008 and my service was registed as http://localhost:8008/EchoService.

    Below are my app.config of my WorkerRole:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
        <system.diagnostics>
            <trace>
                <listeners>
                    <add type="Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener, Microsoft.WindowsAzure.Diagnostics, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                        name="AzureDiagnostics">
                        <filter type="" />
                    </add>
                </listeners>
            </trace>
        </system.diagnostics>

      <system.serviceModel>
        <behaviors>
          <serviceBehaviors>
            <behavior>
              <serviceDebug httpHelpPageEnabled="true" httpsHelpPageEnabled="false" includeExceptionDetailInFaults="true"/>
              <serviceMetadata httpGetEnabled="true" httpsGetEnabled="false"/>
              <dataContractSerializer maxItemsInObjectGraph="65535000"/>
              <serviceThrottling maxConcurrentSessions="100"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>

        <bindings>
          <wsHttpBinding>
            <binding maxReceivedMessageSize="65536000" hostNameComparisonMode="Exact">
              <readerQuotas maxStringContentLength="65536000" maxArrayLength="65536000" maxBytesPerRead="65536000"/>
              <security mode="None"/>
            </binding>
          </wsHttpBinding>
        </bindings>

        <services>
          <service name="WorkerRole1.EchoService">
            <host>
              <baseAddresses>
                <add baseAddress="http://localhost:8008/EchoService"/>
              </baseAddresses>
            </host>
            <endpoint binding="wsHttpBinding"
                      address=""
                      contract="WorkerRole1.IEchoService" />
          </service>
        </services>
      </system.serviceModel>
    </configuration>

    And below is my csdef and cscfg file:

    <?xml version="1.0" encoding="utf-8"?>
    <ServiceDefinition name="WorkerRoleHostWCF" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
      <WorkerRole name="WorkerRole1" vmsize="ExtraSmall">
        <Imports>
          <Import moduleName="Diagnostics" />
          <Import moduleName="RemoteAccess" />
          <Import moduleName="RemoteForwarder" />
        </Imports>
        <Endpoints>
          <InputEndpoint name="Endpoint1" protocol="http" port="8008" />
        </Endpoints>
      </WorkerRole>
    </ServiceDefinition>
    <?xml version="1.0" encoding="utf-8"?>
    <ServiceConfiguration serviceName="WorkerRoleHostWCF" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration" osFamily="1" osVersion="*">
      <Role name="WorkerRole1">
        <Instances count="1" />
        <ConfigurationSettings>
          <Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" value="DefaultEndpointsProtocol=https;AccountName=XXXX;AccountKey=XXXX" />
          <Setting name="Microsoft.WindowsAzure.Plugins.RemoteAccess.Enabled" value="true" />
          <Setting name="Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountUsername" value="XXXX" />
          <Setting name="Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountEncryptedPassword" value="XXXX" />
          <Setting name="Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountExpiration" value="2011-01-16T23:59:59.0000000+08:00" />
          <Setting name="Microsoft.WindowsAzure.Plugins.RemoteForwarder.Enabled" value="true" />
        </ConfigurationSettings>
        <Certificates>
          <Certificate name="Microsoft.WindowsAzure.Plugins.RemoteAccess.PasswordEncryption" thumbprint="XXXX" thumbprintAlgorithm="sha1" />
        </Certificates>
      </Role>
    </ServiceConfiguration>
    • Changed Type Shaun XuMVP Thursday, December 16, 2010 10:35 AM
    •  

All Replies

  • Friday, December 17, 2010 6:36 AM
    Moderator
     
     

    Hi,

    http://localhost:8008/ is not the correct service address for your wcf on azure. You need get the azure external endpoint from RoleEnvironment class and set to servicehost endpoint address in code.

    // define an external endpoint for client traffic
                RoleInstanceEndpoint externalEndPoint =
                    RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["Endpoint1"];

                this.serviceHost.AddServiceEndpoint(
                   typeof(IChatService),
                   binding,
                   String.Format("net.tcp://{0}/ChatService", externalEndPoint.IPEndpoint));

    Thanks,


    Mog Liang
  • Friday, December 17, 2010 10:37 AM
     
      Has Code

    I modified the configuration and my host code like below.

                    var ip = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["Endpoint1"].IPEndpoint;
                    var address = new Uri(string.Format("http://{0}/{1}", ip, typeof(EchoService).Name));
                    _host = new ServiceHost(typeof(EchoService), address);
                    _host.Opened += (sender, e) =>
                        {
                            Trace.WriteLine(string.Format("[INF] Opened at {0}", _host.Description.Endpoints[0].Address));
                        };
                    _host.Open();

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <system.diagnostics>
        <trace>
          <listeners>
            <add type="Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener, Microsoft.WindowsAzure.Diagnostics, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                 name="AzureDiagnostics">
              <filter type="" />
            </add>
          </listeners>
        </trace>
      </system.diagnostics>
      <system.serviceModel>
        <behaviors>
          <serviceBehaviors>
            <behavior>
              <serviceMetadata httpGetEnabled="true"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <bindings>
          <wsHttpBinding>
            <binding hostNameComparisonMode="Exact">
              <security mode="None" />
            </binding>
          </wsHttpBinding>
          <basicHttpBinding>
            <binding hostNameComparisonMode="Exact"/>
          </basicHttpBinding>
        </bindings>
        <services>
          <service name="WorkerRole1.EchoService">
            <endpoint address=""
                      binding="wsHttpBinding"
                      contract="WorkerRole1.IEchoService" />
          </service>
        </services>
      </system.serviceModel>
    </configuration>

    And I also added an attribute on my service class (ref this blog http://itechthoughts.wordpress.com/2009/03/23/hosting-wcf-service-in-windows-azure/)

        [ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]
        public class EchoService : IEchoService
        {
            #region IEchoService Members

            public string Echo(string message)
            {
                var result = string.Format("{0} - {1}", message, DateTime.Now.ToString());
                Trace.WriteLine(string.Format("[SVC] {0}", result));
                return result;
            }

            #endregion
        }

    It works well in the local development fabric (I can use http://localhost:8008/EchoService)

    But after I deployed to azure and visit http://mysvc.cloudapp.net:8008/EchoService I got a HTTP 405 error which said "This error (HTTP 405 Method Not Allowed) means that Internet Explorer was able to connect to the website, but the site has a programming error."

    From this post http://social.msdn.microsoft.com/Forums/en-US/windowsazuremanagement/thread/048ecbe9-c68d-4d22-b73f-8b76c060f204/ Mog said "Besides, Workerrole cannot host http transport wcf, it can only host tcp transport wcf currently."

    I don't know if it's impossible to host a HTTP-based (basicHttp or wsHttp) WCF service from a worker role.

  • Monday, December 20, 2010 7:40 AM
    Moderator
     
     Answered

    Hi,

    windows azure 1.3 provided new feature, which allow users to run some commands with elevated priviledge to config the role environment, we could utilize this feature to call netsh command to config the HTTP.

    For how to register ACL for HTTP certain port, please refer to this article

    http://msdn.microsoft.com/en-us/library/ms733768.aspx

    And for how to utilize startup task, please check new released windows azure platform trainingkit (Dec) 

    http://www.microsoft.com/downloads/en/details.aspx?FamilyID=413e88f8-5966-4a83-b309-53b7b77edf78&displaylang=en (see labs- advanced web and worker role)

    Thanks,


    Mog Liang