Silverlight 应用程序的 Azure WorkerRole 中的 WCF 服务

Posted

技术标签:

【中文标题】Silverlight 应用程序的 Azure WorkerRole 中的 WCF 服务【英文标题】:WCF Service in Azure WorkerRole for Silverlight application 【发布时间】:2012-01-12 15:19:24 【问题描述】:

我有一个托管 WCF 服务的 Windows Azure WorkerRole。此服务应由 Silverlight 应用程序使用。在本地,这工作正常,但是,当我尝试部署它时,需要在角色配置中配置端点(见下图)。

当我删除那个端点“WCFEndpoint”时,一切都在本地正常工作。但是,当它存在时,会发生以下异常:

System.ServiceModel.AddressAlreadyInUseException:HTTP 连接 URL "http://+:9196/GreenwayService/" nicht registrieren, weil der TCP-Port 9196 von einer anderen Anwendung verwendet wird。

英文意思是:HTTP could not register URL "...", because the TCP PORT 9196 is used by another application.

据我了解,端点需要像图片中那样定义,以便在云内部可以访问。

这是我的 app.config:

<?xml version="1.0"?>
<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>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup><system.serviceModel>
        <services>
            <service name="Greenway.AzureWorkerRole.ServiceHosting.CrossDomainService">
                <endpoint address="" behaviorConfiguration="HttpEnableBehavior"
                    binding="webHttpBinding" contract="Greenway.AzureWorkerRole.ServiceHosting.ICrossDomainService" />
                <host>
                    <baseAddresses>
                        <add baseAddress="http://localhost:9196/" />
                    </baseAddresses>
                </host>
            </service>
            <service behaviorConfiguration="GreenwayServiceBehavior" name="Greenway.AzureWorkerRole.ServiceHosting.GreenwayService">
                <endpoint address="" binding="basicHttpBinding" contract="Greenway.AzureWorkerRole.ServiceHosting.IGreenwayService" />
                <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
                <host>
                    <baseAddresses>
                        <add baseAddress="http://localhost:9196/GreenwayService/" />
                    </baseAddresses>
                </host>
            </service>
        </services>

        <behaviors>
          <endpointBehaviors>
            <behavior name="HttpEnableBehavior">
              <webHttp/>
            </behavior>
          </endpointBehaviors>

          <serviceBehaviors>

            <behavior name="GreenwayServiceBehavior">
              <serviceMetadata httpGetEnabled="True"/>
              <serviceDebug includeExceptionDetailInFaults="False" />
            </behavior>
          </serviceBehaviors>
        </behaviors>
    </system.serviceModel>
</configuration>

这是启动服务的代码 sn-p:

ServiceHost greenwayServiceHost = new ServiceHost(typeof(GreenwayService));
ServiceHost crossDomainServiceHost = new ServiceHost(typeof(CrossDomainService));
greenwayServiceHost.Open();
crossDomainServiceHost.Open();

为了在云中托管服务,我需要在这三个地方进行哪些更改?

【问题讨论】:

【参考方案1】:

首要问题是您使用“localhost”作为绑定地址。这在 Windows Azure 中永远不会起作用。 Windows Azure 中的所有流量都被定向(来自负载均衡器)到角色实例 (VM) 的物理内部 IP 地址(也称为 DIP 或直接 IP 地址)。

为了使事情在 Windows azure 中运行,您必须绑定到角色实例的 DIP(直接 IP 地址)并使用输入端点提供的端口。我就是这样做的(对于 Worker Role 和自托管 WCF):

 private void CreateServiceHost()
    
        this._serviceHost = new UnityServiceHost(typeof(MyService));

        var binding = new NetTcpBinding(SecurityMode.None);
        RoleInstanceEndpoint externalEndPoint =
            RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["ServiceEndpoint"];
        string endpoint = String.Format(
            "net.tcp://0/MyService", externalEndPoint.IPEndpoint);
        this._serviceHost.AddServiceEndpoint(typeof(IMyService), binding, endpoint);
        this._serviceHost.Open();
    

这在本地开发和真实的 Azure 环境中 100% 有效。这里要注意的是,我从角色的输入端点的 IPEndpoint 实例动态构建了我的端点。

我很确定,一旦您将服务绑定到您从 RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["WCFEndpoint"]; 获取的实际 IP 地址和端口,您的服务将按预期工作;

【讨论】:

感谢您的精彩解释。我试过了,它在本地也可以在云中运行。只有一个问题:通过我以前的解决方案,我能够使用 Visual Studio 中的“添加服务引用”窗口来使用 WCF 服务。我只需要输入地址,它就会找到服务并自动创建引用。使用修改后的版本,无法添加该参考。你知道这是为什么吗?会不会是跨域的事情?我现在使用的解决方法是最初使用我的旧代码添加引用,然后更改代码。 嗯,我的解决方案是使用基于合同创建的手动服务客户端。但是,在 Visual Studio 中,您可以尝试“在解决方案中发现服务”,而不是键入地址来查找服务。这样 VS 可能能够找到服务并创建本地服务代理类(不过我不确定)。

以上是关于Silverlight 应用程序的 Azure WorkerRole 中的 WCF 服务的主要内容,如果未能解决你的问题,请参考以下文章

使用 azure 托管 silverlight 媒体

Silverlight 3 中的新客户端网络堆栈可以直接连接到 Azure 存储或网格吗?

Windows Azure 服务总线 - 一般问题

如何防止用户调整 silverlight 浏览器外窗口的大小?

WPF/Silverlight 问题:如何添加 A-Z 列表项查看器?

.NET 开发的未来:ASP.NET 还是 WPF/Silverlight/Winforms? [关闭]