2011-12-02 33 views
8

En resumen
¿Cómo accedo a un servicio WCF en localhost cuando estoy alojado en IIS en Azure? Azure no vincula localhost o 127.0.0.1 a mi sitio web.Uso de WCF en Localhost en Azure

detalles
que tiene una aplicación ASP.Net alojado en Azure. He agregado un .svc y algunos flujos de trabajo que quiero usar a través de WCF. Para mantener las cosas simples, mi aplicación web simplemente llama al servicio en localhost, por lo que tengo puntos finales como estos en web.config;

<client> 
    <endpoint address="http://localhost:8080/Router.svc/Case" binding="basicHttpBinding" contract="NewOrbit.ExVerifier.Model.Workflow.Case.ICaseWorkflow" name="Case" /> 
    <endpoint address="http://localhost:8080/Workflow/Case/Case_default1.xamlx" binding="basicHttpBinding" contract="*" name="Case_default1" /> 
</client> 

Esto funciona bien en mi máquina local. El problema es que cuando publico esto en Azure, el sitio web en IIS no obtiene un enlace a localhost, sino que los enlaces son siempre a la dirección IP real del servidor. Se termina pareciéndose a esto en applicationHost.config:

<bindings> 
    <binding protocol="http" bindingInformation="10.61.90.44:80:" /> 
    <binding protocol="https" bindingInformation="10.61.90.44:443:" /> 
    <binding protocol="http" bindingInformation="10.61.90.44:8081:" /> 
</bindings> 

Así, tan pronto como mi aplicación web intenta llamar al servicio en localhost (o 127.0.0.1 para el caso) se produce un error al instante. No hace falta decir que, si conecto al servidor y cambio el enlace, todo estará bien.

Lo que me parece realmente extraño es que hay muchos ejemplos de personas que acceden a los servicios de WCF en localhost en Azure, así que no puedo entender por qué es así. He configurado osFamily en 2 y para depurar esto he habilitado la publicación web y el acceso remoto al escritorio, lo que supongo, en teoría, podría estropear las cosas.

lo que ya he mirado

  • puedo volver a escribir la dirección de punto final en mi código en tiempo de ejecución para sustituir localhost para la dirección real o crear el punto final de forma dinámica como se describe por Ron en las respuestas . Desafortunadamente estoy usando el servicio de enrutamiento WCF para que pueda versionar flujos de trabajo. Esto significa que mi código llama al punto final del enrutador y el enrutador WCF llama por turno al servicio/flujo de trabajo real utilizando un punto final especificado en web.config. No tengo control sobre la resolución de punto final de los servicios de enrutamiento sin, creo, escribiendo un conjunto completo de lógica de enrutamiento que parece ser mucho trabajo cuando todo lo que quiero es llamar a localhost :)
  • Cambiar a usar named tubería; Por desgracia, causa algunos problemas extraños con los flujos de trabajo, probablemente debido a la impresión a doble cara, y estoy en una fecha límite, así que no tengo tiempo para llegar al fondo de eso en el minuto.

Respuesta

1

Bien, así que así es como lo resolví. En mi humilde opinión es un truco, pero al menos funciona.

Básicamente, necesito agregar un enlace "*", así que puedo hacer esto en Powershell. La receta general está aquí: http://blogs.msdn.com/b/tomholl/archive/2011/06/28/hosting-services-with-was-and-iis-on-windows-azure.aspx

Se trata de agregar compatibilidad con Canalizaciones con nombre, pero el principio es el mismo. Acabo de cambiar la secuencia de comandos de PowerShell a:

import-module WebAdministration 
# Set up a binding to 8080 for the services 
Get-WebSite "*Web*" | Foreach-Object { 
    $site = $_; 
    $siteref = "IIS:/Sites/" + $site.Name; 
    New-ItemProperty $siteref -name bindings -value @{protocol="http";bindingInformation="*:8080:"} 
} 

Esto ahora me permite usar http://127.0.0.1:8080/service.svc acceder a mi servicio.

Nota: Es necesario para seguir el resto de la receta para establecer contexto de ejecución elevado y cambiar el modo de ejecución de PowerShell, así que siga cuidadosamente

+0

puede alguien decir por qué esto no es vinculante ya disponible cuando se crea el papel? – BozoJoe

4

Usted tiene que construir la dirección de punto final de forma dinámica.

Paso 1: En su ServiceDefinition.csdef necesita declarar un Endpoint.

<ServiceDefinition name="MyFirstAzureWorkflow" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition"> 
    <WebRole name="WorkflowWeb" vmsize="ExtraSmall"> 
    <Sites> 
     <Site name="Web"> 
     <Bindings> 
      <Binding name="Endpoint1" endpointName="WorkflowService" /> 
     </Bindings> 
     </Site> 
    </Sites> 
    <Endpoints> 
     <InputEndpoint name="WorkflowService" protocol="http" port="80" /> 
    </Endpoints> 
    <Imports> 
     <Import moduleName="Diagnostics" /> 
    </Imports> 
    </WebRole> 
</ServiceDefinition> 

Paso 2: Cuando se quiere llamar al servicio

var endpoint = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["WorkflowService"].IPEndpoint; 
var uri = new Uri(string.Format(
    "http://{0}:{1}/MyService.xamlx", 
    endpoint.Address, 
    endpoint.Port)); 
var proxy = new ServiceClient(
    new BasicHttpBinding(), 
    new EndpointAddress(uri)); 
+0

Gracias Ron. Hice algo similar a esto y aunque funciona bien cuando mi código llama al servicio, utilizo WCF Routing Service y no puedo (fácilmente) controlar cómo el servicio de enrutamiento crea puntos finales, así que debo confiar en lo que hay en la web. config. Buena respuesta al caso general sin embargo, y confirma que no estoy loco así que +1. – Frans