Bien démarrer avec les WebSockets de connexions hybrides Relay dans .NET

Dans ce guide de démarrage rapide, vous créez des applications .NET, à savoir un expéditeur et un récepteur, qui envoient et reçoivent des messages à l’aide de WebSockets de connexions hybrides dans Azure Relay. Pour en savoir plus sur Azure Relay en général, consultez Azure Relay.

Ce démarrage rapide comporte les étapes suivantes :

  1. Créer un espace de noms Relay à l’aide du portail Azure.
  2. Créer une connexion hybride dans cet espace de noms à l’aide du portail Azure.
  3. Écrire une application de console (écouteur) de serveur pour recevoir des messages.
  4. Écrire une application de console (expéditeur) de client pour envoyer des messages.
  5. Exécuter les applications.

Prérequis

Pour effectuer ce didacticiel, vous avez besoin de ce qui suit :

  • Visual Studio 2015 ou version ultérieure. Les exemples de ce didacticiel utilisent Visual Studio 2017.
  • Un abonnement Azure. Si vous n’en avez pas, créez un compte gratuit avant de commencer.

Créer un espace de noms

  1. Connectez-vous au portail Azure.

  2. Sélectionnez Tous les services dans le menu de gauche. Sélectionnez Intégration, recherchez Relais, déplacez la souris sur Relais, puis sélectionnez Créer.

    Screenshot showing the selection of Relays -> Create button.

  3. Dans la page Créer un espace de noms, suivez ces étapes :

    1. Choisissez un abonnement Azure dans lequel créer l’espace de noms.

    2. Pour l’option Groupe de ressources, choisissez un groupe de ressources existant dans lequel placer l’espace de noms, ou créez-en un nouveau.

    3. Donnez un nom à l’espace de noms Relais.

    4. Sélectionnez la région où votre espace de noms doit être hébergé.

    5. Au bas de la page, sélectionnez Examiner et créer.

      Screenshot showing the Create namespace page.

    6. Dans la page Vérifier + créer, sélectionnez Créer.

    7. Après quelques minutes, la page Relais de l’espace de noms s’affiche.

      Screenshot showing the home page for Relay namespace.

Obtenir des informations d'identification d'administration

  1. Dans la page Relais, sélectionnez Stratégies d’accès partagé sur le menu de gauche. `

  2. Dans la page Stratégies d’accès partagé, sélectionnez RootManageSharedAccessKey.

  3. Sous Stratégie SAS : RootManageSharedAccessKey, sélectionnez le bouton Copier à côté de Chaîne de connexion principale. L’action copie la chaîne de connexion dans le Presse-papiers pour l’utiliser plus tard. Copiez cette valeur dans le Bloc-notes ou un autre emplacement temporaire.

  4. Répétez l’étape précédente pour copier et coller la valeur de Clé primaire dans un emplacement temporaire pour une utilisation ultérieure.

    Screenshot showing the connection info for Relay namespace.

Create a hybrid connection

Dans la page Relay de votre espace de noms, procédez comme suit pour créer une connexion hybride.

  1. Dans le menu de gauche, sous Entités, sélectionnez Connexions hybrides, puis + Connexion hybride.

    Screenshot showing the Hybrid Connections page.

  2. Dans la page Créer une connexion hybride, entrez un nom pour la connexion hybride, puis sélectionnez Créer.

    Screenshot showing the Create Hybrid Connection page.

Créer une application de serveur (récepteur)

Dans Visual Studio, écrivez une application console C# pour écouter et recevoir des messages à partir de Relay.

Création d’une application console

Dans Visual Studio, créez un nouveau projet Application de console (.NET Framework).

Ajout du package NuGet de relais

  1. Cliquez avec le bouton droit sur le projet créé puis sélectionnez Gérer les packages NuGet.
  2. Sélectionnez Parcourir, puis recherchez Microsoft.Azure.Relay. Dans les résultats de la recherche, sélectionnez Microsoft Azure Relay.
  3. Sélectionnez Installer pour terminer l’installation. Fermez la boîte de dialogue.

Écrire du code pour recevoir des messages

  1. Au début du fichier Program.cs, remplacez les instructions using actuelles par les instructions using suivantes :

    using System;
    using System.IO;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Net;
    using Microsoft.Azure.Relay;
    
  2. Ajoutez des constantes à la classe Program pour les détails de la connexion hybride. Remplacez les espaces réservés par les valeurs obtenues lors de la création de la connexion hybride. Veillez à utiliser le nom de l’espace de noms qualifié complet.

    // replace {RelayNamespace} with the name of your namespace
    private const string RelayNamespace = "YOUR-RELAY-NAMESPACE-NAME.servicebus.windows.net";
    
    // replace {HybridConnectionName} with the name of your hybrid connection
    private const string ConnectionName = "HYBRID-CONNECTION-NAME";
    
    // replace {SAKKeyName} with the name of your Shared Access Policies key, which is RootManageSharedAccessKey by default
    private const string KeyName = "SAS-KEY-NAME";
    
    // replace {SASKey} with the primary key of the namespace you saved earlier
    private const string Key = "SAS-KEY-VALUE";
    
  3. Ajoutez la méthode ProcessMessagesOnConnection à la classe Program :

    // The method initiates the connection.
    private static async void ProcessMessagesOnConnection(HybridConnectionStream relayConnection, CancellationTokenSource cts)
    {
        Console.WriteLine("New session");
    
        // The connection is a fully bidrectional stream. 
        // Put a stream reader and a stream writer over it.  
        // This allows you to read UTF-8 text that comes from 
        // the sender, and to write text replies back.
        var reader = new StreamReader(relayConnection);
        var writer = new StreamWriter(relayConnection) { AutoFlush = true };
        while (!cts.IsCancellationRequested)
        {
            try
            {
                // Read a line of input until a newline is encountered.
                var line = await reader.ReadLineAsync();
    
                if (string.IsNullOrEmpty(line))
                {
                    // If there's no input data, signal that 
                    // you will no longer send data on this connection,
                    // and then break out of the processing loop.
                    await relayConnection.ShutdownAsync(cts.Token);
                    break;
                }
    
                // Write the line on the console.
                Console.WriteLine(line);
    
                // Write the line back to the client, prepended with "Echo:"
                await writer.WriteLineAsync($"Echo: {line}");
            }
            catch (IOException)
            {
                // Catch an I/O exception. This likely occurred when
                // the client disconnected.
                Console.WriteLine("Client closed connection");
                break;
            }
        }
    
        Console.WriteLine("End session");
    
        // Close the connection.
        await relayConnection.CloseAsync(cts.Token);
    }
    
  4. Ajoutez la méthode RunAsync à la classe Program :

    private static async Task RunAsync()
    {
        var cts = new CancellationTokenSource();
    
        var tokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider(KeyName, Key);
        var listener = new HybridConnectionListener(new Uri(string.Format("sb://{0}/{1}", RelayNamespace, ConnectionName)), tokenProvider);
    
        // Subscribe to the status events.
        listener.Connecting += (o, e) => { Console.WriteLine("Connecting"); };
        listener.Offline += (o, e) => { Console.WriteLine("Offline"); };
        listener.Online += (o, e) => { Console.WriteLine("Online"); };
    
        // Opening the listener establishes the control channel to
        // the Azure Relay service. The control channel is continuously 
        // maintained, and is reestablished when connectivity is disrupted.
        await listener.OpenAsync(cts.Token);
        Console.WriteLine("Server listening");
    
        // Provide callback for the cancellation token that will close the listener.
        cts.Token.Register(() => listener.CloseAsync(CancellationToken.None));
    
        // Start a new thread that will continuously read the console.
        new Task(() => Console.In.ReadLineAsync().ContinueWith((s) => { cts.Cancel(); })).Start();
    
        // Accept the next available, pending connection request. 
        // Shutting down the listener allows a clean exit. 
        // This method returns null.
        while (true)
        {
            var relayConnection = await listener.AcceptConnectionAsync();
            if (relayConnection == null)
            {
                break;
            }
    
            ProcessMessagesOnConnection(relayConnection, cts);
        }
    
        // Close the listener after you exit the processing loop.
        await listener.CloseAsync(cts.Token);
    }
    
  5. Ajoutez la ligne de code suivante à la méthode Main dans la classe Program :

    RunAsync().GetAwaiter().GetResult();
    

    Le fichier Program.cs final doit ressembler à cela :

    namespace Server
    {
        using System;
        using System.IO;
        using System.Threading;
        using System.Threading.Tasks;
        using Microsoft.Azure.Relay;
    
        public class Program
        {
            private const string RelayNamespace = "{RelayNamespace}.servicebus.windows.net";
            private const string ConnectionName = "{HybridConnectionName}";
            private const string KeyName = "{SASKeyName}";
            private const string Key = "{SASKey}";
    
            public static void Main(string[] args)
            {
                RunAsync().GetAwaiter().GetResult();
            }
    
            private static async Task RunAsync()
            {
                var cts = new CancellationTokenSource();
    
                var tokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider(KeyName, Key);
                var listener = new HybridConnectionListener(new Uri(string.Format("sb://{0}/{1}", RelayNamespace, ConnectionName)), tokenProvider);
    
                // Subscribe to the status events.
                listener.Connecting += (o, e) => { Console.WriteLine("Connecting"); };
                listener.Offline += (o, e) => { Console.WriteLine("Offline"); };
                listener.Online += (o, e) => { Console.WriteLine("Online"); };
    
                // Opening the listener establishes the control channel to
                // the Azure Relay service. The control channel is continuously 
                // maintained, and is reestablished when connectivity is disrupted.
                await listener.OpenAsync(cts.Token);
                Console.WriteLine("Server listening");
    
                // Provide callback for a cancellation token that will close the listener.
                cts.Token.Register(() => listener.CloseAsync(CancellationToken.None));
    
                // Start a new thread that will continuously read the console.
                new Task(() => Console.In.ReadLineAsync().ContinueWith((s) => { cts.Cancel(); })).Start();
    
                // Accept the next available, pending connection request. 
                // Shutting down the listener allows a clean exit. 
                // This method returns null.
                while (true)
                {
                    var relayConnection = await listener.AcceptConnectionAsync();
                    if (relayConnection == null)
                    {
                        break;
                    }
    
                    ProcessMessagesOnConnection(relayConnection, cts);
                }
    
                // Close the listener after you exit the processing loop.
                await listener.CloseAsync(cts.Token);
            }
    
            private static async void ProcessMessagesOnConnection(HybridConnectionStream relayConnection, CancellationTokenSource cts)
            {
                Console.WriteLine("New session");
    
                // The connection is a fully bidrectional stream. 
                // Put a stream reader and a stream writer over it.  
                // This allows you to read UTF-8 text that comes from 
                // the sender, and to write text replies back.
                var reader = new StreamReader(relayConnection);
                var writer = new StreamWriter(relayConnection) { AutoFlush = true };
                while (!cts.IsCancellationRequested)
                {
                    try
                    {
                        // Read a line of input until a newline is encountered.
                        var line = await reader.ReadLineAsync();
    
                        if (string.IsNullOrEmpty(line))
                        {
                            // If there's no input data, signal that 
                            // you will no longer send data on this connection.
                            // Then, break out of the processing loop.
                            await relayConnection.ShutdownAsync(cts.Token);
                            break;
                        }
    
                        // Write the line on the console.
                        Console.WriteLine(line);
    
                        // Write the line back to the client, prepended with "Echo:"
                        await writer.WriteLineAsync($"Echo: {line}");
                    }
                    catch (IOException)
                    {
                        // Catch an I/O exception. This likely occurred when
                        // the client disconnected.
                        Console.WriteLine("Client closed connection");
                        break;
                    }
                }
    
                Console.WriteLine("End session");
    
                // Close the connection.
                await relayConnection.CloseAsync(cts.Token);
            }
        }
    }
    

Créer une application cliente (expéditeur)

Dans Visual Studio, écrivez une application console C# pour envoyer des messages à Relay.

Création d’une application console

Dans Visual Studio, créez un nouveau projet Application de console (.NET Framework).

Ajout du package NuGet de relais

  1. Cliquez avec le bouton droit sur le projet créé puis sélectionnez Gérer les packages NuGet.
  2. Sélectionnez Parcourir, puis recherchez Microsoft.Azure.Relay. Dans les résultats de la recherche, sélectionnez Microsoft Azure Relay.
  3. Sélectionnez Installer pour terminer l’installation. Fermez la boîte de dialogue.

Écrire du code pour envoyer des messages

  1. Au début du fichier Program.cs, remplacez les instructions using actuelles par les instructions using suivantes :

    using System;
    using System.IO;
    using System.Threading;
    using System.Threading.Tasks;
    using Microsoft.Azure.Relay;
    
  2. Ajoutez des constantes à la classe Program pour les détails de la connexion hybride. Remplacez les espaces réservés par les valeurs obtenues lors de la création de la connexion hybride. Veillez à utiliser le nom de l’espace de noms qualifié complet.

    // replace {RelayNamespace} with the name of your namespace
    private const string RelayNamespace = "YOUR-RELAY-NAMESPACE-NAME.servicebus.windows.net";
    
    // replace {HybridConnectionName} with the name of your hybrid connection
    private const string ConnectionName = "HYBRID-CONNECTION-NAME";
    
    // replace {SAKKeyName} with the name of your Shared Access Policies key, which is RootManageSharedAccessKey by default
    private const string KeyName = "SAS-KEY-NAME";
    
    // replace {SASKey} with the primary key of the namespace you saved earlier
    private const string Key = "SAS-KEY-VALUE";
    
  3. Ajoutez la méthode suivante à la classe Program :

    private static async Task RunAsync()
    {
        Console.WriteLine("Enter lines of text to send to the server with ENTER");
    
        // Create a new hybrid connection client.
        var tokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider(KeyName, Key);
        var client = new HybridConnectionClient(new Uri(String.Format("sb://{0}/{1}", RelayNamespace, ConnectionName)), tokenProvider);
    
        // Initiate the connection.
        var relayConnection = await client.CreateConnectionAsync();
    
        // Run two concurrent loops on the connection. One 
        // reads input from the console and writes it to the connection 
        // with a stream writer. The other reads lines of input from the 
        // connection with a stream reader and writes them to the console. 
        // Entering a blank line shuts down the write task after 
        // sending it to the server. The server then cleanly shuts down
        // the connection, which terminates the read task.
    
        var reads = Task.Run(async () => {
            // Initialize the stream reader over the connection.
            var reader = new StreamReader(relayConnection);
            var writer = Console.Out;
            do
            {
                // Read a full line of UTF-8 text up to newline.
                string line = await reader.ReadLineAsync();
                // If the string is empty or null, you are done.
                if (String.IsNullOrEmpty(line))
                    break;
                // Write to the console.
                await writer.WriteLineAsync(line);
            }
            while (true);
        });
    
        // Read from the console and write to the hybrid connection.
        var writes = Task.Run(async () => {
            var reader = Console.In;
            var writer = new StreamWriter(relayConnection) { AutoFlush = true };
            do
            {
                // Read a line from the console.
                string line = await reader.ReadLineAsync();
                // Write the line out, also when it's empty.
                await writer.WriteLineAsync(line);
                // Quit when the line is empty,
                if (String.IsNullOrEmpty(line))
                    break;
            }
            while (true);
        });
    
        // Wait for both tasks to finish.
        await Task.WhenAll(reads, writes);
        await relayConnection.CloseAsync(CancellationToken.None);
    }
    
  4. Ajoutez la ligne de code suivante à la méthode Main dans la classe Program.

    RunAsync().GetAwaiter().GetResult();
    

    Le fichier Program.cs doit ressembler à cela :

    using System;
    using System.IO;
    using System.Threading;
    using System.Threading.Tasks;
    using Microsoft.Azure.Relay;
    
    namespace Client
    {
        class Program
        {
            private const string RelayNamespace = "{RelayNamespace}.servicebus.windows.net";
            private const string ConnectionName = "{HybridConnectionName}";
            private const string KeyName = "{SASKeyName}";
            private const string Key = "{SASKey}";
    
            static void Main(string[] args)
            {
                RunAsync().GetAwaiter().GetResult();
            }
    
            private static async Task RunAsync()
            {
                Console.WriteLine("Enter lines of text to send to the server with ENTER");
    
                // Create a new hybrid connection client.
                var tokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider(KeyName, Key);
                var client = new HybridConnectionClient(new Uri(String.Format("sb://{0}/{1}", RelayNamespace, ConnectionName)), tokenProvider);
    
                // Initiate the connection.
                var relayConnection = await client.CreateConnectionAsync();
    
                // Run two concurrent loops on the connection. One 
                // reads input from the console and then writes it to the connection 
                // with a stream writer. The other reads lines of input from the 
                // connection with a stream reader and then writes them to the console. 
                // Entering a blank line shuts down the write task after 
                // sending it to the server. The server then cleanly shuts down
                // the connection, which terminates the read task.
    
                var reads = Task.Run(async () => {
                    // Initialize the stream reader over the connection.
                    var reader = new StreamReader(relayConnection);
                    var writer = Console.Out;
                    do
                    {
                        // Read a full line of UTF-8 text up to newline.
                        string line = await reader.ReadLineAsync();
                        // If the string is empty or null, you are done.
                        if (String.IsNullOrEmpty(line))
                            break;
                        // Write to the console.
                        await writer.WriteLineAsync(line);
                    }
                    while (true);
                });
    
                // Read from the console and write to the hybrid connection.
                var writes = Task.Run(async () => {
                    var reader = Console.In;
                    var writer = new StreamWriter(relayConnection) { AutoFlush = true };
                    do
                    {
                        // Read a line from the console.
                        string line = await reader.ReadLineAsync();
                        // Write the line out, also when it's empty.
                        await writer.WriteLineAsync(line);
                        // Quit when the line is empty.
                        if (String.IsNullOrEmpty(line))
                            break;
                    }
                    while (true);
                });
    
                // Wait for both tasks to finish.
                await Task.WhenAll(reads, writes);
                await relayConnection.CloseAsync(CancellationToken.None);
            }
        }
    }
    

Exécution des applications

  1. Exécutez l’application de serveur.

  2. Exécutez l’application cliente et entrez du texte.

  3. Vérifiez que la console d’application de serveur affiche le texte entré dans l’application cliente.

    Console windows testing both the server and client applications.

Félicitations, vous avez créé une application de connexions hybrides complète !

Étapes suivantes

Dans ce guide de démarrage rapide, vous avez créé des applications cliente et serveur .NET qui utilisent des WebSockets pour envoyer et recevoir des messages. La fonctionnalité Connexions hybrides d’Azure Relay permet également d’envoyer et de recevoir des messages avec HTTP. Pour apprendre à utiliser HTTP avec des connexions hybrides Azure Relay, consultez le guide de démarrage rapide de HTTP.

Dans ce guide de démarrage rapide, vous avez utilisé le .NET Framework pour créer des applications cliente et serveur. Pour apprendre à écrire des applications cliente et serveur à l’aide de Node.js, consultez le guide de démarrage rapide de WebSockets dans Node.js ou le guide de démarrage rapide de HTTP dans Node.js.