We are facing issues to establish control channel with relay hybrid connection. We referred below URL and it works well with console application however it is not working with web application/web API.
https://docs.microsoft.com/en-us/azure/service-bus-relay/relay-hybrid-connections-dotnet-get-started
Please note that my application works well with console application as listener. Also, we already verified all relay namespace, access key, connection name, access key are correct.
Issue- While debugging listener application (I am using web API as listener) nothing is happening and not even exception and moving to next line of code when debug hits to below line-
await listener.OpenAsync(cts.Token);
Below is my whole listener code-
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Net.Sockets;
using Microsoft.Azure.Relay;
using System.Threading.Tasks;
using System.IO;
using System.Threading;
using System.Web.WebSockets;
namespace WebAPI.Controllers
{
public class ValuesController : ApiController
{
private const string RelayNamespace = "{Relay Namespace}";
private const string ConnectionName = "{Connection Name}";
private const string KeyName = "{Policy Name}";
private const string Key = "{Key}";
// GET api/values
public IEnumerable<string> Get()
{
RunAsync().GetAwaiter().GetResult();
return new string[] { "value1", "value2" };
}
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 will establish the control channel to
// the Azure Relay service. The control channel will be continuously
// maintained and reestablished when connectivity is disrupted.
await listener.OpenAsync(cts.Token);
string str = "Ping me";
Console.WriteLine("Server listening");
// Providing callback for 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 will allow a clean exit with
// this method returning null
while (true)
{
var relayConnection = await listener.AcceptConnectionAsync();
if (relayConnection == null)
{
break;
}
ProcessMessagesOnConnection(relayConnection, cts);
}
// Close the listener after we 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.
// We put a stream reader and a stream writer over it
// which allows us 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, we will signal that
// we will no longer send data on this connection
// and then break out of the processing loop.
await relayConnection.ShutdownAsync(cts.Token);
break;
}
// Output the line on the console
Console.WriteLine(line);
// Write the line back to the client, prepending "Echo:"
await writer.WriteLineAsync($"Echo: {line}");
}
catch (IOException)
{
// Catch an IO exception that is likely caused because
// the client disconnected.
Console.WriteLine("Client closed connection");
break;
}
}
Console.WriteLine("End session");
// Closing the connection
await relayConnection.CloseAsync(cts.Token);
}
// GET api/values/5
public string Get(int id)
{
return "value";
}
// POST api/values
public void Post([FromBody]string value)
{
}
// PUT api/values/5
public void Put(int id, [FromBody]string value)
{
}
// DELETE api/values/5
public void Delete(int id)
{
}
}
}