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
1. Create a Namespace
Get Managed credentials
Create Hybrid Connection
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);
}
}
}