none
WorkerRole HTTP Input Endpoint on Azure Emulator

    Question

  • Hi

    I'm trying to implement the following scenario:

    • Several WorkerRoles hosting a SOAP and REST services on http Input endpoints
    • Several WebRoles with one http Input endpoint. Communicating WorkerRoles through Input endpoints.

    Following this tip:

    http://code.msdn.microsoft.com/WCF-Azure-Worker-Role-on-b394df49

    I've managed to register http Input endpoints on WorkerRole instances. However when I tried to run multiple worker instances on emulator I got an error exception:

    System.ServiceModel.AddressAlreadyInUseException: HTTP could not register URL http://+:

    To solve that issue I needed to set the HostnameComparsionMode to Exact. But then I started getting 405 Method not allowed when I tried to access the endpoints through load balanced endpoint (on emulator 127.0.0.1:port).

    All endpoints are reachable on the internal endpoints (127.255.0.x:port).

    The question is how can I have Http Input endpoints emulated on multiple WorkerRole instances ?

    Example Solution to reproduce problem: https://www.dropbox.com/s/378oaqotdp0axen/HttpRolesTest.zip

    UPDATE:

    Setting HostnameComparsionMode to StrongWildcard solves problem for the real Azure.

    However I am still not able to test several Worker roles with Http Inputs on emulator. According to this blog load balancing does not work correctly with WCF endpoints with HostnameComparsionMode.Exact. Does anyone know why it is not possible to use HostnameComparsionMode.Exact ?







    Wednesday, September 26, 2012 12:17 PM

Answers

  • Hi,

    Based on my test setting HostnameComparsionMode.Exact should return 404. It's because when HostnameComparsionMode.Exact is set it requires the host name exactly matches the registered listen URL. The current load balancer of the emulator does not quite support this scenario. Say you post to:

    http://localhost:port/YourService where port is the external port, the load balancer will delegate the request to one instance of the worker role but the raw Uri in the request is:

    http://localhost:portlocal/Yourservice where portlocal is the local port. The http://localhost:portlocal doesn't match the registered listen URL (which should be http://127.255.0.0:portlocal, etc.)

    This means it's difficult to leverage load balancer of the emulator to test basicHttpBinding based WCF in Worker Role if you set HostnameComparsionMode.Exact. So in this case, I suggest you use a client side load balancer to simulate (when you start service you'll be able to know the local endpoints. Then in WCF client, randomly pick local endpoint to send request, namely 127.255.0.0, etc.) as a simple workaround. This issue should not appear for published Worker Role as you don't use HostnameComparsionMode.Exact for published application.

    Another option is to use another binding such as netTcpBinding. Before deployment you can change the binding to basicHttpBinding. (You may need to pay attention to the difference between netTcpBinding and basicHttpBinding though)


    Allen Chen [MSFT]
    MSDN Community Support | Feedback to us













    Wednesday, October 10, 2012 4:48 AM

All replies

  • Hi,

    By default the value is StrongWildcard. The actual cause is weak wildcard does not work in the emulator, as different instances uses different host names and ports. Please refer to http://blogs.msdn.com/b/avkashchauhan/archive/2011/10/03/handling-quot-system-servicemodel-addressalreadyinuseexception-http-could-not-register-url-quot-exception-in-compute-emulator-with-windows-azure-sdk-1-5.aspx for an explanation.

    Best Regards,

    Ming Xu.


    Please mark the replies as answers if they help or unmark if not.
    If you have any feedback about my replies, please contact msdnmg@microsoft.com.
    Microsoft One Code Framework

    • Proposed as answer by Carlos Sardo Sunday, October 07, 2012 2:10 PM
    • Unproposed as answer by Grzegorz Banczak Monday, October 08, 2012 8:06 AM
    Saturday, October 06, 2012 5:25 PM
  • Thank you for the reply !

    Actually the reason why the WeakWildcard does not work on emulated environment is pretty clear for me. 

    However setting the hostname comparison mode on:

    • StrongWildcard gives me

    System.ServiceModel.AddressAlreadyInUseException: HTTP could not register URL http://+:

    Which is reasonable since all the instances try to reserve addresses like http://+:port/Service

    • Exact gives me 405 Method not allowed on input address. Which I would like to solve or explain somehow.





    Monday, October 08, 2012 7:47 AM
  • Hi,

    As pointed out in http://blogs.msdn.com/b/avkashchauhan/archive/2011/10/03/handling-quot-system-servicemodel-addressalreadyinuseexception-http-could-not-register-url-quot-exception-in-compute-emulator-with-windows-azure-sdk-1-5.aspx, you can bind to the specific IP rather than using the weak wildcard "+" so when you run your multiple instances based Windows Azure application in compute emulator it will not cause the above described error. If you have further concerns, you can also feel free to post a comment on the blog post.

    Best Regards,

    Ming Xu.


    Please mark the replies as answers if they help or unmark if not.
    If you have any feedback about my replies, please contact msdnmg@microsoft.com.
    Microsoft One Code Framework

    Monday, October 08, 2012 11:17 AM
  • Hi,

    Probably I should post this snippet before, instead of linking the whole solution... As you can see I have already bound the ServiceHost base address to IP address (RoleEnvionment assigns address like 127.255.0.x). However ServiceHost with HostnameComparsionMode set to StrongWildcard will always try to reserve address like http://+:port/Service no matter what base address the host will have. AFIK the only way of binding host to a specific address is to use HostnameComparsionMode set to Exact, which gives me 405.

            public override void Run()
            {
                // This is a sample worker implementation. Replace with your logic.
                Trace.WriteLine("WorkerRole entry point called", "Information");
    
                var endpoint = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints.First().Value;
                var ub = new UriBuilder();
                ub.Host = endpoint.IPEndpoint.Address.ToString();
                ub.Port = endpoint.IPEndpoint.Port;
                ub.Scheme = "http";
                ub.Path = "Service";
                var host = new ServiceHost(typeof (Service), ub.Uri);
                host.AddDefaultEndpoints();
                host.Description.Behaviors.Add(new ServiceMetadataBehavior() {HttpGetEnabled = true});
                host.Description.Behaviors.Add(new OverrideWCFAddressFilterServiceBehavior());
                foreach (var e in host.Description.Endpoints)
                {
                    ((BasicHttpBinding)e.Binding).HostNameComparisonMode = HostNameComparisonMode.Exact;
                }
                host.Open();
                foreach(var e in host.Description.Endpoints)
                {
                    Trace.WriteLine("Host listening on " + e.ListenUri.ToString());
                }
                while (true)
                {
                    Thread.Sleep(10000);
                    Trace.WriteLine("Working", "Information");
                }
            }

    Monday, October 08, 2012 12:40 PM
  • Hi,

    Based on my test setting HostnameComparsionMode.Exact should return 404. It's because when HostnameComparsionMode.Exact is set it requires the host name exactly matches the registered listen URL. The current load balancer of the emulator does not quite support this scenario. Say you post to:

    http://localhost:port/YourService where port is the external port, the load balancer will delegate the request to one instance of the worker role but the raw Uri in the request is:

    http://localhost:portlocal/Yourservice where portlocal is the local port. The http://localhost:portlocal doesn't match the registered listen URL (which should be http://127.255.0.0:portlocal, etc.)

    This means it's difficult to leverage load balancer of the emulator to test basicHttpBinding based WCF in Worker Role if you set HostnameComparsionMode.Exact. So in this case, I suggest you use a client side load balancer to simulate (when you start service you'll be able to know the local endpoints. Then in WCF client, randomly pick local endpoint to send request, namely 127.255.0.0, etc.) as a simple workaround. This issue should not appear for published Worker Role as you don't use HostnameComparsionMode.Exact for published application.

    Another option is to use another binding such as netTcpBinding. Before deployment you can change the binding to basicHttpBinding. (You may need to pay attention to the difference between netTcpBinding and basicHttpBinding though)


    Allen Chen [MSFT]
    MSDN Community Support | Feedback to us













    Wednesday, October 10, 2012 4:48 AM
  • Thank you for your reply.

    Yes it actually works on published environment. Most of my services will be exposed as RESTful services so I cannot use netTcpBinding instead. But the solution with "emulating" LB on the client side should do the trick.

    Wednesday, October 10, 2012 9:35 AM