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 服务的主要内容,如果未能解决你的问题,请参考以下文章
Silverlight 3 中的新客户端网络堆栈可以直接连接到 Azure 存储或网格吗?
如何防止用户调整 silverlight 浏览器外窗口的大小?