2011-12-02 25 views
8

In sintesi
Come accedere ad un servizio WCF su localhost quando ospitato in IIS su Azure? Azure non associa localhost o 127.0.0.1 al mio sito web.Utilizzo di WCF su Localhost su Azure

dettagli
Ho un'applicazione ASP.Net ospitato su Azure. Ho aggiunto un .svc e alcuni flussi di lavoro che voglio usare tramite WCF. Per mantenere le cose semplici, la mia app web chiama semplicemente il servizio su localhost, quindi ho endpoint come questi in 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> 

Questo funziona perfettamente sul mio computer locale. Il problema è che quando lo pubblico su Azure, il sito Web in IIS non ottiene un binding a localhost, invece i binding sono sempre all'indirizzo IP reale del server. Si finisce per guardare come questo in 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> 

Così, non appena il mio web app tenta di chiamare il servizio su localhost (127.0.0.1 o per quella materia) non riesce immediatamente. Inutile dire che se rpifico il server e cambio il binding, tutto va bene.

Quello che trovo davvero strano è che ci sono un sacco di esempi là fuori dove le persone stanno accedendo ai servizi WCF su localhost su Azure, quindi non riesco a capire perché sia ​​così. Ho impostato osFamily su 2 e per eseguire il debug di questo ho abilitato la pubblicazione sul Web e l'accesso al desktop remoto che, in teoria, in teoria, potrebbero rovinare tutto.

Quello che ho già guardato

  • posso riscrivere l'indirizzo dell'endpoint nel mio codice in fase di esecuzione per sostituire localhost per l'indirizzo effettivo o creare il punto finale in modo dinamico, come descritto da Ron nelle risposte . Sfortunatamente sto usando il servizio di routing WCF così posso gestire i flussi di lavoro della versione. Ciò significa che il mio codice chiama l'endpoint del router e il router WCF a sua volta chiama il servizio/flusso di lavoro effettivo utilizzando un endpoint specificato in web.config. Non ho il controllo sulla risoluzione dell'endpoint dei servizi di routing senza, credo, scrivendo un intero set di logica di routing che sembra essere molto lavoro quando tutto ciò che voglio è chiamare localhost :)
  • Passaggio all'utilizzo denominato tubi; Purtroppo, causa alcuni problemi strani con i flussi di lavoro, probabilmente a causa del duplexing, e io sono su una scadenza quindi non ho il tempo di arrivare al fondo di questo al minuto.

risposta

1

Ok, quindi è così che l'ho risolto. IMHO è un hack ma almeno funziona.

Fondamentalmente, ho bisogno di aggiungere un bind "*", quindi posso farlo in PowerShell. La ricetta generale è qui: http://blogs.msdn.com/b/tomholl/archive/2011/06/28/hosting-services-with-was-and-iis-on-windows-azure.aspx

Questo riguarda l'aggiunta del supporto Named Pipes, ma il principio è lo stesso. Ho appena cambiato lo script PowerShell per:

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:"} 
} 

Questo ora mi permette di utilizzare http://127.0.0.1:8080/service.svc di accedere al mio servizio.

Nota: Si ha bisogno di seguire il resto della ricetta per impostare contesto di esecuzione elevata e modificare la modalità di esecuzione di PowerShell, in modo da seguire con attenzione

+0

chiunque può dire perché questo non è vincolante già disponibili al momento della creazione del ruolo? – BozoJoe

4

Devi costruire l'indirizzo dell'endpoint in modo dinamico.

Passaggio 1: In ServiceDefinition.csdef è necessario dichiarare 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> 

Fase 2: Quando si desidera chiamare il servizio

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

Grazie Ron. Ho fatto qualcosa di simile a questo e mentre funziona bene quando il mio codice chiama il servizio, io uso il servizio di routing WCF e non posso (facilmente) controllare come il servizio di routing crea endpoint, quindi devo fare affidamento su ciò che è nel web. config. Buona risposta al caso generale però, e conferma che non sono pazzo quindi +1. – Frans