Come usare gli inoltri WCF di Inoltro di Azure con .NETHow to use Azure Relay WCF relays with .NET

Questo articolo descrive come usare il servizio di inoltro di Azure.This article describes how to use the Azure Relay service. Negli esempi, scritti in C#, viene usata l'API di Windows Communication Foundation (WCF) con le estensioni contenute nell'assembly del bus di servizio.The samples are written in C# and use the Windows Communication Foundation (WCF) API with extensions contained in the Service Bus assembly. Per altre informazioni, vedere la panoramica del servizio di inoltro di Azure.For more information about Azure relay, see the Azure Relay overview.

Nota

Per completare l'esercitazione, è necessario un account Azure.To complete this tutorial, you need an Azure account. È possibile attivare i benefici della sottoscrizione MSDN o iscriversi per un account gratuito.You can activate your MSDN subscriber benefits or sign up for a free account.

Informazioni sull'inoltro WCFWhat is WCF Relay?

Il servizio di inoltro WCF di Azure consente di creare applicazioni ibride eseguite sia in un data center di Azure che nell'ambiente aziendale locale.The Azure WCF Relay service enables you to build hybrid applications that run in both an Azure datacenter and your own on-premises enterprise environment. Il servizio di inoltro facilita questo compito consentendo di esporre in modo sicuro nel cloud pubblico i servizi WCF (Windows Communication Foundation) che risiedono in una rete aziendale senza dover aprire una connessione firewall o richiedere modifiche di notevole impatto a un'infrastruttura di rete aziendale.The relay service facilitates this by enabling you to securely expose Windows Communication Foundation (WCF) services that reside within a corporate enterprise network to the public cloud, without having to open a firewall connection, or requiring intrusive changes to a corporate network infrastructure.

Concetti sull'inoltro con WCF

Il servizio di inoltro di Azure consente di ospitare servizi WCF nell'ambiente aziendale esistente.Azure Relay enables you to host WCF services within your existing enterprise environment. È quindi possibile delegare l'ascolto delle sessioni e delle richieste in ingresso per questi servizi WCF al servizio di inoltro in esecuzione in Azure.You can then delegate listening for incoming sessions and requests to these WCF services to the relay service running within Azure. In questo modo è possibile esporre tali servizi al codice dell'applicazione in esecuzione in Azure oppure ad ambienti destinati a personale che accede da dispositivi mobili o a partner che accedono tramite Extranet.This enables you to expose these services to application code running in Azure, or to mobile workers or extranet partner environments. Il servizio di inoltro consente di controllare in modo sicuro ed estremamente dettagliato quali utenti possono accedere ai servizi.Relay enables you to securely control who can access these services at a fine-grained level. È uno strumento efficace e sicuro per esporre dati e funzionalità dell'applicazione dalle soluzioni aziendali esistenti e di sfruttarle dal cloud.It provides a powerful and secure way to expose application functionality and data from your existing enterprise solutions and take advantage of it from the cloud.

Questo articolo illustra come usare il servizio di inoltro di Azure per creare un servizio Web WCF, esposto con un'associazione di canale TCP, che implementa una conversazione sicura tra due parti.This article discusses how to use Azure Relay to create a WCF web service, exposed using a TCP channel binding, that implements a secure conversation between two parties.

Per iniziare a usare le entità di messaggistica del bus di servizio in Azure, prima di tutto è necessario creare uno spazio dei nomi con un nome univoco in Azure. Uno spazio dei nomi fornisce un contenitore di ambito per fare riferimento alle risorse del bus di servizio all'interno dell'applicazione.

Per creare uno spazio dei nomi:

  1. Accedere al portale di Azure.
  2. Nel riquadro di spostamento sinistro del portale fare clic su + Crea una risorsa, quindi su Enterprise Integration e infine su Bus di servizio.
  3. Nella finestra di dialogo Crea spazio dei nomi immettere un nome per lo spazio dei nomi. Verrà effettuato immediatamente un controllo sulla disponibilità del nome.
  4. Dopo aver verificato che il nome dello spazio dei nomi sia disponibile, scegliere il piano tariffario, ovvero Basic, Standard o Premium.
  5. Nel campo Sottoscrizione scegliere una sottoscrizione di Azure in cui creare lo spazio dei nomi.
  6. Nel campo Gruppo di risorse scegliere un gruppo di risorse esistente nel quale risiederà lo spazio dei nomi oppure crearne uno nuovo.
  7. In Localitàscegliere il paese o l'area in cui deve essere ospitato lo spazio dei nomi.

    Crea spazio dei nomi

  8. Fare clic su Crea. A questo punto, lo spazio dei nomi verrà creato e abilitato nel sistema. Potrebbero essere necessari alcuni minuti per consentire al sistema di effettuare il provisioning delle risorse per lo spazio dei nomi creato.

Ottenere le credenziali di gestione

Con la creazione di un nuovo spazio dei nomi viene generata automaticamente una regola di firma di accesso condiviso iniziale con una coppia associata di chiavi primaria e secondaria, ognuna delle quali concede il controllo completo su tutti gli aspetti dello spazio dei nomi. Per informazioni su come creare altre regole con diritti più limitati per mittenti e ricevitori normali, vedere Autenticazione e autorizzazione del bus di servizio. Per copiare la regola iniziale seguire questa procedura:

  1. Fare clic su Tutte le risorse, quindi sul nome dello spazio dei nomi appena creato.
  2. Nella finestra dello spazio dei nomi fare clic su Criteri di accesso condiviso.
  3. Nella schermata Criteri di accesso condiviso fare clic su RootManageSharedAccessKey.

    connection-info

  4. Nella finestra Criteri: RootManageSharedAccessKey fare clic sul pulsante Copia accanto a Stringa di connessione - chiave primaria per copiare la stringa di connessione negli Appunti e usarla in un secondo momento. Incollare questo valore nel Blocco note o in un'altra posizione temporanea.

    connection-string

  5. Ripetere il passaggio precedente e copiare e incollare il valore della chiave primaria in un percorso temporaneo per usarlo in seguito.

Ottenere il pacchetto NuGet del bus di servizioGet the Service Bus NuGet package

Il pacchetto NuGet del bus di servizio è il modo più semplice per recuperare l'API del bus di servizio e configurare l'applicazione con tutte le dipendenze di tale servizio.The Service Bus NuGet package is the easiest way to get the Service Bus API and to configure your application with all of the Service Bus dependencies. Per installare il pacchetto NuGet nel progetto, eseguire queste operazioni:To install the NuGet package in your project, do the following:

  1. In Esplora soluzioni fare clic con il pulsante destro del mouse su Riferimenti e scegliere Gestisci pacchetti NuGet.In Solution Explorer, right-click References, then click Manage NuGet Packages.
  2. Cercare "Bus di servizio" e selezionare la voce Bus di servizio di Microsoft Azure .Search for "Service Bus" and select the Microsoft Azure Service Bus item. Fare clic su Installa per completare l'installazione e alla fine chiudere la finestra di dialogo successiva:Click Install to complete the installation, then close the following dialog box:

Esporre e utilizzare un servizio Web SOAP con TCPExpose and consume a SOAP web service with TCP

Per esporre un servizio Web SOAP WCF esistente per l'utilizzo esterno, è necessario apportare modifiche alle associazioni e agli indirizzi del servizio.To expose an existing WCF SOAP web service for external consumption, you must make changes to the service bindings and addresses. A seconda di come sono stati installati e configurati i servizi WCF, potrebbe essere necessario modificare il file di configurazione o il codice.This may require changes to your configuration file or it could require code changes, depending on how you have set up and configured your WCF services. Si noti che WCF consente di usare più endpoint di rete con lo stesso servizio, quindi è possibile mantenere gli endpoint interni esistenti aggiungendo al tempo stesso endpoint di inoltro per l'accesso esterno.Note that WCF allows you to have multiple network endpoints over the same service, so you can retain the existing internal endpoints while adding relay endpoints for external access at the same time.

In questa attività si crea un semplice servizio WCF e si aggiunge un listener di inoltro a tale servizio.In this task, you build a simple WCF service and add a relay listener to it. Per questo esercizio si presuppone una certa conoscenza di Visual Studio, pertanto non è inclusa una spiegazione dettagliata della procedura di creazione di un progetto,This exercise assumes some familiarity with Visual Studio, and therefore does not walk through all the details of creating a project. ma l'attenzione è rivolta principalmente al codice.Instead, it focuses on the code.

Prima di iniziare, completare questa procedura per configurare l'ambiente:Before starting these steps, complete the following procedure to set up your environment:

  1. In Visual Studio creare un'applicazione console contenente due progetti, "Client" e "Service", all'interno della soluzione.Within Visual Studio, create a console application that contains two projects, "Client" and "Service", within the solution.
  2. Aggiungere il pacchetto NuGet del bus di servizio a entrambi i progetti.Add the Service Bus NuGet package to both projects. Questo pacchetto aggiunge ai progetti tutti i riferimenti ad assembly necessari.This package adds all the necessary assembly references to your projects.

Come creare il servizioHow to create the service

Creare innanzitutto il servizio stesso.First, create the service itself. Tutti i servizi WCF sono costituiti da almeno tre parti distinte:Any WCF service consists of at least three distinct parts:

  • Definizione di un contratto che descrive i messaggi da scambiare e le operazioni da richiamare.Definition of a contract that describes what messages are exchanged and what operations are to be invoked.
  • Implementazione di tale contratto.Implementation of that contract.
  • Host che ospita il servizio WCF ed espone diversi endpoint.Host that hosts the WCF service and exposes several endpoints.

Negli esempi di codice di questa sezione vengono trattati singolarmente tutti questi componenti.The code examples in this section address each of these components.

Il contratto consente di definire una singola operazione, AddNumbers, che somma due numeri e restituisce il risultato.The contract defines a single operation, AddNumbers, that adds two numbers and returns the result. L'interfaccia IProblemSolverChannel consente al client di gestire più facilmente la durata del proxy.The IProblemSolverChannel interface enables the client to more easily manage the proxy lifetime. La creazione di tale interfaccia rientra tra le procedure consigliate.Creating such an interface is considered a best practice. È opportuno inserire questa definizione del contratto in un file separato in modo da potervi fare riferimento da entrambi i progetti "Client" e "Service", ma è comunque possibile copiare il codice in entrambi i progetti.It's a good idea to put this contract definition into a separate file so that you can reference that file from both your "Client" and "Service" projects, but you can also copy the code into both projects.

using System.ServiceModel;

[ServiceContract(Namespace = "urn:ps")]
interface IProblemSolver
{
    [OperationContract]
    int AddNumbers(int a, int b);
}

interface IProblemSolverChannel : IProblemSolver, IClientChannel {}

Dopo che il contratto è stato definito, l'implementazione è la seguente:With the contract in place, the implementation is as follows:

class ProblemSolver : IProblemSolver
{
    public int AddNumbers(int a, int b)
    {
        return a + b;
    }
}

Configurare un host del servizio a livello di codiceConfigure a service host programmatically

Una volta definiti il contratto e l'implementazione, è ora possibile ospitare il servizio.With the contract and implementation in place, you can now host the service. L'hosting viene eseguito all'interno di un oggetto System.ServiceModel.ServiceHost, che si occupa della gestione delle istanze del servizio e ospita gli endpoint che sono in ascolto dei messaggi.Hosting occurs inside a System.ServiceModel.ServiceHost object, which takes care of managing instances of the service and hosts the endpoints that listen for messages. Il codice seguente configura il servizio sia con un normale endpoint locale che con un endpoint di inoltro per illustrare come si presentano gli endpoint interni ed esterni affiancati.The following code configures the service with both a regular local endpoint and a relay endpoint to illustrate the appearance, side by side, of internal and external endpoints. Sostituire la stringa namespace con il nome dello spazio dei nomi e yourKey con la chiave SAS ottenuta nel passaggio di impostazione precedente.Replace the string namespace with your namespace name and yourKey with the SAS key that you obtained in the previous setup step.

ServiceHost sh = new ServiceHost(typeof(ProblemSolver));

sh.AddServiceEndpoint(
   typeof (IProblemSolver), new NetTcpBinding(),
   "net.tcp://localhost:9358/solver");

sh.AddServiceEndpoint(
   typeof(IProblemSolver), new NetTcpRelayBinding(),
   ServiceBusEnvironment.CreateServiceUri("sb", "namespace", "solver"))
    .Behaviors.Add(new TransportClientEndpointBehavior {
          TokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider("RootManageSharedAccessKey", "<yourKey>")});

sh.Open();

Console.WriteLine("Press ENTER to close");
Console.ReadLine();

sh.Close();

Nell'esempio vengono creati due endpoint inclusi nella stessa implementazione del contratto:In the example, you create two endpoints that are on the same contract implementation. Uno è locale e uno viene proiettato tramite il servizio di inoltro.One is local and one is projected through Azure Relay. Le differenze principali tra di essi sono costituite dalle associazioni: NetTcpBinding per l'endpoint locale e NetTcpRelayBinding per l'endpoint e gli indirizzi di inoltro.The key differences between them are the bindings; NetTcpBinding for the local one and NetTcpRelayBinding for the relay endpoint and the addresses. L'endpoint locale è dotato di un indirizzo di rete locale con una porta distinta.The local endpoint has a local network address with a distinct port. L'endpoint di inoltro ha un indirizzo costituito dalla stringa sb, dal nome dello spazio dei nomi e dal percorso "solver".The relay endpoint has an endpoint address composed of the string sb, your namespace name, and the path "solver." Si ottiene così l'URI sb://[serviceNamespace].servicebus.windows.net/solver, che identifica l'endpoint del servizio come endpoint TCP (di inoltro) del bus di servizio con nome DNS esterno completo.This results in the URI sb://[serviceNamespace].servicebus.windows.net/solver, identifying the service endpoint as a Service Bus (relay) TCP endpoint with a fully qualified external DNS name. Se si inserisce il codice sostituendo i segnaposto nella funzione Main dell'applicazione Service, si otterrà un servizio funzionante.If you place the code replacing the placeholders into the Main function of the Service application, you will have a functional service. Se si vuole che il servizio sia in ascolto esclusivamente sull'inoltro, rimuovere la dichiarazione dell'endpoint locale.If you want your service to listen exclusively on the relay, remove the local endpoint declaration.

Come configurare un host del servizio nel file App.configConfigure a service host in the App.config file

È anche possibile configurare l'host usando il file App.config.You can also configure the host using the App.config file. L'esempio seguente in questo caso visualizza il codice del servizio di hosting.The service hosting code in this case appears in the next example.

ServiceHost sh = new ServiceHost(typeof(ProblemSolver));
sh.Open();
Console.WriteLine("Press ENTER to close");
Console.ReadLine();
sh.Close();

Le definizioni dell'endpoint vengono spostate nel file App.config.The endpoint definitions move into the App.config file. Il pacchetto NuGet ha già aggiunto al file App.config una serie di definizioni, che sono le estensioni di configurazione necessarie per il servizio di inoltro.The NuGet package has already added a range of definitions to the App.config file, which are the required configuration extensions for Azure Relay. L'esempio seguente, che è l'esatto equivalente di quello riportato in precedenza, deve essere inserito direttamente sotto l'elemento system.serviceModel.The following example, which is the exact equivalent of the previous code, should appear directly beneath the system.serviceModel element. In questo esempio di codice si presuppone che il nome dello spazio dei nomi del progetto C# sia Service.This code example assumes that your project C# namespace is named Service. Sostituire i segnaposto con la chiave di firma di accesso condiviso e il nome dello spazio dei nomi dell'inoltro.Replace the placeholders with your relay namespace name and SAS key.

<services>
    <service name="Service.ProblemSolver">
        <endpoint contract="Service.IProblemSolver"
                  binding="netTcpBinding"
                  address="net.tcp://localhost:9358/solver"/>
        <endpoint contract="Service.IProblemSolver"
                  binding="netTcpRelayBinding"
                  address="sb://<namespaceName>.servicebus.windows.net/solver"
                  behaviorConfiguration="sbTokenProvider"/>
    </service>
</services>
<behaviors>
    <endpointBehaviors>
        <behavior name="sbTokenProvider">
            <transportClientEndpointBehavior>
                <tokenProvider>
                    <sharedAccessSignature keyName="RootManageSharedAccessKey" key="<yourKey>" />
                </tokenProvider>
            </transportClientEndpointBehavior>
        </behavior>
    </endpointBehaviors>
</behaviors>

Dopo aver apportato queste modifiche, il servizio viene avviato come in precedenza, ma con due endpoint dinamici, uno locale e l'altro in ascolto nel cloud.After you make these changes, the service starts as it did before, but with two live endpoints: one local and one listening in the cloud.

Creare il clientCreate the client

Configurare un client a livello di codiceConfigure a client programmatically

Per usare il servizio, è possibile costruire un client WCF tramite un oggetto ChannelFactory.To consume the service, you can construct a WCF client using a ChannelFactory object. Il bus di servizio usa un modello di sicurezza basato sui token implementato tramite la firma di accesso condiviso.Service Bus uses a token-based security model implemented using SAS. La classe TokenProvider rappresenta un provider di token di sicurezza con metodi factory incorporati che restituiscono alcuni provider di token noti.The TokenProvider class represents a security token provider with built-in factory methods that return some well-known token providers. L'esempio seguente usa il metodo CreateSharedAccessSignatureTokenProvider per gestire l'acquisizione del token SAS appropriato.The following example uses the CreateSharedAccessSignatureTokenProvider method to handle the acquisition of the appropriate SAS token. Il nome e la chiave sono quelli ottenuti dal portale come descritto nella sezione precedente.The name and key are those obtained from the portal as described in the previous section.

In primo luogo, fare riferimento o copiare nel progetto client il codice del contratto IProblemSolver del servizio.First, reference or copy the IProblemSolver contract code from the service into your client project.

Sostituire quindi il codice nel metodo Main del client, anche in questo caso sostituendo il testo segnaposto con la chiave di firma di accesso condiviso e lo spazio dei nomi dell'inoltro.Then, replace the code in the Main method of the client, again replacing the placeholder text with your relay namespace and SAS key.

var cf = new ChannelFactory<IProblemSolverChannel>(
    new NetTcpRelayBinding(),
    new EndpointAddress(ServiceBusEnvironment.CreateServiceUri("sb", "<namespaceName>", "solver")));

cf.Endpoint.Behaviors.Add(new TransportClientEndpointBehavior
            { TokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider("RootManageSharedAccessKey","<yourKey>") });

using (var ch = cf.CreateChannel())
{
    Console.WriteLine(ch.AddNumbers(4, 5));
}

È ora possibile compilare il client e il servizio ed eseguirli (con il servizio per primo), in modo che il client chiami il servizio e visualizzi 9.You can now build the client and the service, run them (run the service first), and the client calls the service and prints 9. È possibile eseguire il client e il server in computer diversi, persino in reti diverse, senza riscontrare problemi di comunicazione.You can run the client and server on different machines, even across networks, and the communication will still work. Il codice client può inoltre essere eseguito nel cloud o in locale.The client code can also run in the cloud or locally.

Configurare un client nel file App.configConfigure a client in the App.config file

Il codice seguente illustra come configurare il client usando il file App.config.The following code shows how to configure the client using the App.config file.

var cf = new ChannelFactory<IProblemSolverChannel>("solver");
using (var ch = cf.CreateChannel())
{
    Console.WriteLine(ch.AddNumbers(4, 5));
}

Le definizioni dell'endpoint vengono spostate nel file App.config.The endpoint definitions move into the App.config file. L'esempio seguente, che è identico al codice riportato in precedenza, deve essere inserito direttamente sotto l'elemento <system.serviceModel>.The following example, which is the same as the code listed previously, should appear directly beneath the <system.serviceModel> element. Anche in questo caso, come in precedenza, è necessario sostituire i segnaposto con la chiave di firma di accesso condiviso e lo spazio dei nomi dell'inoltro.Here, as before, you must replace the placeholders with your relay namespace and SAS key.

<client>
    <endpoint name="solver" contract="Service.IProblemSolver"
              binding="netTcpRelayBinding"
              address="sb://<namespaceName>.servicebus.windows.net/solver"
              behaviorConfiguration="sbTokenProvider"/>
</client>
<behaviors>
    <endpointBehaviors>
        <behavior name="sbTokenProvider">
            <transportClientEndpointBehavior>
                <tokenProvider>
                    <sharedAccessSignature keyName="RootManageSharedAccessKey" key="<yourKey>" />
                </tokenProvider>
            </transportClientEndpointBehavior>
        </behavior>
    </endpointBehaviors>
</behaviors>

Passaggi successiviNext steps

A questo punto, dopo aver appreso le nozioni di base del servizio di inoltro di Azure, selezionare i collegamenti seguenti per altre informazioni.Now that you've learned the basics of Azure Relay, follow these links to learn more.