Aan de slag met websockets voor hybride verbindingen in Azure Relay in .NET
In deze snelstart maakt u .NET maakt u toepassingen voor afzenders en ontvangers waarmee berichten worden verzonden en ontvangen met behulp van websockets voor hybride verbindingen in Azure Relay. Zie Azure Relay voor meer informatie over Azure Relay in het algemeen.
In deze snelstart voert u de volgende stappen uit:
- Een Relay-naamruimte maken met behulp van Azure Portal.
- Een hybride verbinding in die naamruimte maken met behulp van Azure Portal.
- Een serverconsoletoepassing (listener) schrijven om berichten te ontvangen.
- Een clientconsoletoepassing (afzender) schrijven om berichten te verzenden.
- Toepassingen uitvoeren.
Vereisten
Voor het voltooien van deze zelfstudie moet aan de volgende vereisten worden voldaan:
- Visual Studio 2015 of hoger. In de voorbeelden in deze zelfstudie wordt Visual Studio 2017 gebruikt.
- Een Azure-abonnement. Als u nog geen abonnement hebt, maakt u een gratis account voordat u begint.
Een naamruimte maken
Meld u aan bij het Azure-portaal.
Selecteer Alle services in het linkermenu. Selecteer Integratie, zoek naar Relays, beweeg de muis over Relays en selecteer Vervolgens Maken.
Voer op de pagina Naamruimte maken de volgende stappen uit:
Kies een Azure-abonnement waarin u de naamruimte wilt maken.
Kies bij Resourcegroep een bestaande resourcegroep waarin de naamruimte moet worden geplaatst of maak een nieuwe resourcegroep.
Voer een naam in voor de Relay-naamruimte.
Selecteer de regio waarin uw naamruimte moet worden gehost.
Selecteer Controleren en maken onderaan de pagina.
Selecteer Maken op de pagina Beoordelen en maken.
Na enkele minuten ziet u de Relay-pagina voor de naamruimte.
Beheerreferenties ophalen
Selecteer op de pagina Relay beleid voor gedeelde toegang in het menu links. `
Selecteer RootManageSharedAccessKey op de pagina Beleid voor gedeelde toegang.
Selecteer onder SAS-beleid: RootManageSharedAccessKey de knop Kopiëren naast primaire verbindingsreeks. Met deze actie kopieert u de verbindingsreeks naar het Klembord voor later gebruik. Plak deze waarde in Kladblok of een andere tijdelijke locatie.
Herhaal de vorige stap om de waarde voor de Primaire sleutel te kopiëren en plakken naar een tijdelijke locatie zodat u deze later kunt gebruiken.
Een hybride verbinding maken
Volg deze stappen op de relaypagina voor uw naamruimte om een hybride verbinding te maken.
Selecteer hybride verbindingen in het linkermenu onder Entiteiten en selecteer vervolgens + Hybride verbinding.
Voer op de pagina Hybride verbinding maken een naam in voor de hybride verbinding en selecteer Maken.
Een servertoepassing (listener) maken
Maak in Visual Studio een C#-consoletoepassing om berichten van de Relay te beluisteren en te ontvangen.
Een consoletoepassing maken
Maak in Visual Studio een nieuw Console-app (.NET Framework)-project.
Het pakket Relay NuGet toevoegen
- Klik met de rechtermuisknop op het nieuwe project en selecteer NuGet-pakketten beheren.
- Selecteer Bladeren en zoek naar Microsoft.Azure.Relay. Selecteer Microsoft Azure Relay in de lijst met zoekresultaten.
- Selecteer Installeren om de installatie uit te voeren. Sluit het dialoogvenster.
Code schrijven om berichten te ontvangen
Vervang de bestaande
using
-instructies bovenaan het bestand Program.cs door de volgendeusing
-instructies:using System; using System.IO; using System.Threading; using System.Threading.Tasks; using System.Net; using Microsoft.Azure.Relay;
Voeg constanten toe aan de klasse
Program
voor de gegevens van de hybride verbinding. Vervang de tijdelijke aanduidingen door de waarden die u hebt verkregen bij het maken van de hybride verbinding. Zorg ervoor dat u de volledig gekwalificeerde naamruimte gebruikt.// 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";
Voeg de
ProcessMessagesOnConnection
-methode toe aan de klasseProgram
:// 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); }
Voeg de
RunAsync
-methode toe aan de klasseProgram
: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); }
Voeg de volgende coderegel toe aan de methode
Main
in de klasseProgram
:RunAsync().GetAwaiter().GetResult();
Het voltooide bestand Program.cs moet er als volgt uitzien:
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); } } }
Een clienttoepassing maken (afzender)
Maak in Visual Studio een C#-consoletoepassing om berichten naar de Relay te sturen.
Een consoletoepassing maken
Maak in Visual Studio een nieuw Console-app (.NET Framework)-project.
Het pakket Relay NuGet toevoegen
- Klik met de rechtermuisknop op het nieuwe project en selecteer NuGet-pakketten beheren.
- Selecteer Bladeren en zoek naar Microsoft.Azure.Relay. Selecteer Microsoft Azure Relay in de lijst met zoekresultaten.
- Selecteer Installeren om de installatie uit te voeren. Sluit het dialoogvenster.
Code schrijven om berichten te verzenden
Vervang de bestaande
using
-instructies bovenaan het bestand Program.cs door de volgendeusing
-instructies:using System; using System.IO; using System.Threading; using System.Threading.Tasks; using Microsoft.Azure.Relay;
Voeg constanten toe aan de klasse
Program
voor de gegevens van de hybride verbinding. Vervang de tijdelijke aanduidingen door de waarden die u hebt verkregen bij het maken van de hybride verbinding. Zorg ervoor dat u de volledig gekwalificeerde naamruimte gebruikt.// 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";
Voeg de volgende methode toe aan de klasse
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); }
Voeg de volgende coderegel toe aan de methode
Main
in de klasseProgram
.RunAsync().GetAwaiter().GetResult();
Het bestand Program.cs moet er dan zo uitzien:
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); } } }
Notitie
De voorbeeldcode in dit artikel maakt gebruik van een verbindingsreeks voor verificatie bij een Azure Relay-naamruimte om de zelfstudie eenvoudig te houden. U wordt aangeraden Microsoft Entra ID-verificatie te gebruiken in productieomgevingen, in plaats van gebruik te maken van verbindingsreeks s of handtekeningen voor gedeelde toegang, die gemakkelijker kunnen worden aangetast. Zie Een toepassing verifiëren en autoriseren met Microsoft Entra ID voor toegang tot Azure Relay-entiteiten en een beheerde identiteit verifiëren met Microsoft Entra ID voor toegang tot Azure Relay-entiteiten en een beheerde identiteit verifiëren met Microsoft Entra-id voor toegang tot Azure Relay-resources voor gedetailleerde informatie en voorbeeldcode voor het gebruik van de Microsoft Entra-id.
De toepassingen uitvoeren
Voer de servertoepassing uit.
Voer de clienttoepassing uit en voer wat tekst in.
Zorg ervoor dat de servertoepassingsconsole de tekst weergeeft die in de clienttoepassing is ingevoerd.
Gefeliciteerd, u hebt een volledige toepassing voor hybride verbindingen gemaakt.
Volgende stappen
In deze snelstart hebt u .NET toepassingen gemaakt voor afzenders en ontvangers waarmee berichten worden verzonden en ontvangen met behulp van websockets. De hybride verbindingsfunctie van Azure Relay ondersteunt tevens HTTP voor het verzenden en ontvangen van berichten. Zie de snelstart over HTTP voor informatie over het gebruik van HTTP met hybride verbindingen van Azure Relay.
In deze snelstart hebt u .NET Framework gebruikt om client- en servertoepassingen te maken. Zie de snelstart over WebSockets in Node.js of de snelstart over HTTP in Node.js voor informatie over het schrijven van client- en servertoepassingen in Node.js.