Search code examples
c#azuretcpportazure-cloud-services

Exposing a port externally in Azure Compute Emulator


I have made an Azure Cloud Service TCP listener in C#, and now I am trying to debug it locally. The service definition below exposes the port I am interested in, but when it is running locally, the address is bound to localhost, which is not visible to other devices on the same network.

<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="Foo.Listener.Azure" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition" schemaVersion="2015-04.2.6">
  <WorkerRole name="Foo.Listener" vmsize="Small">
    <ConfigurationSettings>
      <Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" />
    </ConfigurationSettings>
    <Endpoints>
      <InputEndpoint name="Foo Protocol" protocol="tcp" port="9100" localPort="9100" />
    </Endpoints>
  </WorkerRole>
</ServiceDefinition>

I have tried adding a port proxy with the following command:

netsh interface portproxy add v4tov4 listenport=9100 connectaddress=localhost connectport=9100 protocol=tcp

However, the compute emulator seems to think the port number 9100 is in use when I do this, and it chooses 9101 instead. How can I run my worker role locally, and allow it to accept external connections?


Solution

  • I managed to get this working by adding a check in the worker role. It's not pretty, and I'd much rather have this done through configuration than through code, but here's my solution:

    IEnumerable<IPEndPoint> endpoints;
    
    if (RoleEnvironment.IsEmulated)
    {
        endpoints = Dns.GetHostEntry(Dns.GetHostName())
            .AddressList
            .Select(address => new IPEndPoint(address, 9100));
    }
    else
    {
        endpoints = RoleEnvironment.CurrentRoleInstance
            .InstanceEndpoints
            .Select(endpoint => endpoint.Value.IPEndpoint);
    }