有没有办法以编程方式确定Azure DevFabric中端点使用的实际IP?

时间:2011-07-15 16:38:45

标签: azure azure-compute-emulator

我正在Azure开发结构下托管一个IIS应用程序。

将应用程序部署到Azure计算模拟器时,会创建一个临时IIS应用程序,用于侦听5100左右的端口。来自公共端点的传入请求将重定向到此端口。

但是,似乎Azure开发结构并不总是使用已在项目配置中声明的公共端口。因此,例如,我们的应用程序应该公开一个公共端口80 - 但是当我运行它时,它几乎总是端口81,但有时是端口82,依此类推。

所以我可以确保在我的应用程序中创建的URL是正确的,我想知道这个外部端口是什么。

不幸的是,我不能简单地查看Request.Url.Port,因为这是临时应用程序的端口号 - 通常是5100. RoleEnvironment.CurrentRoleInstance.InstanceEndpoints,不起作用,因为它也将端口返回为从服务器上看,5100及以下。

4 个答案:

答案 0 :(得分:1)

通过使用Reflector查看csrun.exe来解决这个问题。

SDK DLL Microsoft.ServiceHost.Tools.DevelopmentFabric似乎是关键,特别是方法FabricClient.GetServiceDeployments()FabricClient.GetServiceInformation()。所以:

using System; using Microsoft.ServiceHosting.Tools.DevelopmentFabric;

class Program
{
    static void Main(string[] args)
    {
        FabricClient client = FabricClient.CreateFabricClient();

        foreach (string tenantName in client.GetServiceDeployments())
        {
            var information = client.GetServiceInformation(tenantName);
            foreach (var item in information)
            {
                Console.WriteLine(string.Format("{0} {1} {2} {3}", item.ContractName, item.InterfaceName, item.UrlSpecification, item.Vip));
            }
        }

        Console.ReadLine();
    }
}

class Program { static void Main(string[] args) { FabricClient client = FabricClient.CreateFabricClient(); foreach (string tenantName in client.GetServiceDeployments()) { var information = client.GetServiceInformation(tenantName); foreach (var item in information) { Console.WriteLine(string.Format("{0} {1} {2} {3}", item.ContractName, item.InterfaceName, item.UrlSpecification, item.Vip)); } } Console.ReadLine(); } }

我所追求的是

请注意,显然,这只适用于开发结构......但无论如何,这就是我在这里寻找的。

答案 1 :(得分:0)

您尝试使用

吗?
RoleEnvironment.CurrentRoleInstance.InstanceEndpoints

我不确定atm,因为我不在我的电脑后面,但很快就会仔细检查。无论如何,在每个端点上都有一个属性IPEndPoint,它也有端口。如果你也获得了公共端点(我认为你对当前的角色实例做了什么),你应该能够从那里获得地址。

希望它有所帮助...

答案 2 :(得分:0)

我认为“错误”端口的原因,如81/82等,是所需的端口正忙。

可能你有其他应用程序正在侦听端口80,因此它永远不可用。此外,我已经多次看到模拟器中的Azure计算实例没有足够快地关闭,所以如果你启动一个新实例它会获得下一个端口,等等。如果我杀了它,等一下再重新开始 - 它会得到满足端口。

它绝不应该是生产中的问题,这可能是它没有通过API公开的原因。在测试期间,请确保您没有与其他应用程序发生冲突,并且您需要一些时间让计算机笔记干净地关闭并释放端口。

答案 3 :(得分:0)

我无法让dev结构组件为我工作(看起来像API已经改变),所以我使用解析“csrun / status”的输出来查找给定角色名称的IP地址。这里有一些获取IP的代码,但你需要做一些额外的工作来获取端口。

public static string GetEmulatorIPAddress(string roleName)
    {
        var psi = new ProcessStartInfo();
        psi.FileName = @"C:\Program Files\Microsoft SDKs\Windows Azure\Emulator\csrun.exe";
        psi.Arguments = "/status";
        psi.RedirectStandardOutput = true;
        psi.RedirectStandardError = true;
        psi.RedirectStandardInput = true;
        psi.UseShellExecute = false;
        psi.CreateNoWindow = true;

        StringBuilder sb = new StringBuilder();

        DataReceivedEventHandler errorHandler = (object sender, DataReceivedEventArgs e) =>
            {

            };

        string lastIPAddress = null;
        string foundIPAddress = null;

        DataReceivedEventHandler dataHandler = (object sender, DataReceivedEventArgs e) =>
        {
            string line = e.Data;
            if (line != null && foundIPAddress == null)
            {
                if (line.StartsWith("EndPoint: http://"))
                {
                    int ipStart = line.IndexOf("://") + "://".Length;
                    int ipEnd = line.IndexOf(":", ipStart);
                    lastIPAddress = line.Substring(ipStart, ipEnd - ipStart);
                }

                if (line.Trim() == roleName)
                {
                    foundIPAddress = lastIPAddress;
                }
            }
        };

        Process p = new Process();
        p.StartInfo = psi;
        p.ErrorDataReceived += errorHandler;
        p.OutputDataReceived += dataHandler;
        p.EnableRaisingEvents = true;
        p.Start();
        p.BeginOutputReadLine();
        p.BeginErrorReadLine();

        p.WaitForExit();

        return foundIPAddress;
    }