Wednesday, March 26, 2025

Hybrid Connections WebSockets in Azure Relay

Hybrid Connections WebSockets in Azure Relay

Source: https://learn.microsoft.com/en-us/azure/azure-relay/relay-hybrid-connections-dotnet-get-started

1. Create a Namespace





Get Managed credentials 

Create Hybrid Connection 


2. Create a server application (listener)

using Microsoft.Azure.Relay;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace myserver
{
    public class Program
    {
        private const string RelayNamespace = "sreerelay.servicebus.windows.net";
        private const string ConnectionName = "sreehybridconn";
        private const string KeyName = "RootManageSharedAccessKey";
        private const string Key = "Wtcg6qDIGI4aFts+qYH+zmHwCL1Q=";

        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);
            listener.Connecting += (o, e) => { Console.WriteLine("Connecting"); };
            listener.Offline += (o, e) => { Console.WriteLine("Offline"); };
            listener.Online += (o, e) => { Console.WriteLine("Online"); };
            await listener.OpenAsync(cts.Token);
            Console.WriteLine("Server listening");
            cts.Token.Register(() => listener.CloseAsync(CancellationToken.None));
            new Task(() => Console.In.ReadLineAsync().ContinueWith((s) => {
            cts.Cancel(); })).Start();
            while (true)
            {
                var relayConnection = await listener.AcceptConnectionAsync();
                if (relayConnection == null)
                {
                    break;
                }
                ProcessMessagesOnConnection(relayConnection, cts);
            }
            await listener.CloseAsync(cts.Token);
        }

        private static async void ProcessMessagesOnConnection(HybridConnectionStream
        relayConnection, CancellationTokenSource cts)
        {
            Console.WriteLine("New session");
            var reader = new StreamReader(relayConnection);
            var writer = new StreamWriter(relayConnection) { AutoFlush = true };
            while (!cts.IsCancellationRequested)
            {
                try
                {
                    var line = await reader.ReadLineAsync();
                    if (string.IsNullOrEmpty(line))
                    {
                        await relayConnection.ShutdownAsync(cts.Token);
                        break;
                    }
                    Console.WriteLine(line);
                    await writer.WriteLineAsync($"Echo: {line}");
                }
                catch (IOException)
                {
                    Console.WriteLine("Client closed connection");
                    break;
                }
            }
            Console.WriteLine("End session");
            await relayConnection.CloseAsync(cts.Token);
        }
    }
}


3. Create a client application (sender)

using Microsoft.Azure.Relay;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace myclient
{
    class Program
    {
        private const string RelayNamespace = "sreerelay.servicebus.windows.net";
        private const string ConnectionName = "sreehybridconn";
        private const string KeyName = "RootManageSharedAccessKey";
        private const string Key = "Wtcg6qDIGI4aFts+qYH+zmHwCL1Q=";

        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");
            var tokenProvider =
            TokenProvider.CreateSharedAccessSignatureTokenProvider(KeyName, Key);
            var client = new HybridConnectionClient(new Uri(String.Format(
            "sb://{0}/{1}", RelayNamespace, ConnectionName)), tokenProvider);
            var relayConnection = await client.CreateConnectionAsync();

            var reads = Task.Run(async () =>
            {
                var reader = new StreamReader(relayConnection);
                var writer = Console.Out;
                do
                {
                    string line = await reader.ReadLineAsync();
                    if (String.IsNullOrEmpty(line))
                        break;
                    await writer.WriteLineAsync(line);
                }
                while (true);
            });

            var writes = Task.Run(async () =>
            {
                var reader = Console.In;
                var writer = new StreamWriter(relayConnection) { AutoFlush = true };
                do
                {
                    string line = await reader.ReadLineAsync();
                    await writer.WriteLineAsync(line);
                    if (String.IsNullOrEmpty(line))
                        break;
                }
                while (true);
            });
           
            await Task.WhenAll(reads, writes);
            await relayConnection.CloseAsync(CancellationToken.None);
        }
    }
}


OutPut:


No comments:

Post a Comment

Featured Post

Building Secure APIs with FastAPI and Azure AD Authentication

Building Secure APIs with FastAPI and Azure AD Authentication Published on September 2, 2025 In today's world of microservices and API-f...

Popular posts