How to read data from a websocket hosted on Azure API Management using a C# ClientWebSocket?

194 Views Asked by At

I have the following architecture piece that I am trying to test.

enter image description here

My goal is to read data published to Azure API Management through the AzurePubSub using a WebSocket client from my C# Console App. Azure PubSub is another element you are seeing on green that exposes a WebSocket endpoint that I am not going to make public for my clients. As part of Azure Api Management, I can expose it to external clients using a subscription key and my organization URL.

Using code from this repo: azure pubsub examples I was able to tap into the Azure PubSub element directly to read and write data from there. Here is my AzurePubSubSubscriber using the above repo

using System;
using System.Threading.Tasks;

using Azure.Messaging.WebPubSub;

using Websocket.Client;

namespace subscriber
{
    class Program
    {
        static async Task Main(string[] args)
        {
            var connectionString = "Endpoint=https://pubsub.webpubsub.azure.com;AccessKey=myaccesskey;Version=1.0;";
            var hub = "myhub";

            // Either generate the URL or fetch it from server or fetch a temp one from the portal
            var serviceClient = new WebPubSubServiceClient(connectionString, hub);
            var url = serviceClient.GetClientAccessUri();

            using (var client = new WebsocketClient(url))
            {
                // Disable the auto disconnect and reconnect because the sample would like the client to stay online even no data comes in
                client.ReconnectTimeout = null;
                client.MessageReceived.Subscribe(msg => Console.WriteLine($"Message received: {msg}"));
                await client.Start();
                Console.WriteLine("Connected.");
                Console.Read();
            }
        }
    }
}

Here is my AzurePubSubPublisher

using System.Threading.Tasks;
using Azure;
using Azure.Core;
using Azure.Messaging.WebPubSub;

namespace publisher
{
    class Program
    {
        static async Task Main(string[] args)
        {
            await Method1();
        }

        public static async Task Method1()
        {
            var connectionString = $"Endpoint=https://pubsub.webpubsub.azure.com;AccessKey=myaccesskey;Version=1.0;";
            var hub = "myhub";

            while (true)
            {
                Console.WriteLine("Write your message");
                var message = Console.ReadLine();

                if (string.IsNullOrEmpty(message))
                {
                    return;
                }

                // Either generate the token or fetch it from server or fetch a temp one from the portal
                var serviceClient = new WebPubSubServiceClient(connectionString, hub);
                await serviceClient.SendToAllAsync(message);
            }
        }
    }
}

Now when I expose the endpoint through the Azure API Management to consume content from my Console C# App is where I am not receiving data and am not sure what I am missing here.

Here is the C# code I used from my Console App to read data from Azure API Management endpoint:

   static async Task Main()
    {
        await StartWebSocketClient4();
        Console.ReadLine();
    }

    static async Task StartWebSocketClient4()
    {
        try
        {
            Console.Write("Connecting....");
            var cts = new CancellationTokenSource();
            var socket = new ClientWebSocket();
           
            string wsUri = "wss://myorganization.com/sub?subscription-key=ac3529b7619a383dc6ce6e618dbc9b7614a66";

            await socket.ConnectAsync(new Uri(wsUri), cts.Token);
            Console.WriteLine(socket.State);

            await Task.Factory.StartNew(
                async () =>
                {
                    var rcvBytes = new byte[1024 * 1024];
                    var rcvBuffer = new ArraySegment<byte>(rcvBytes);
                    while (true)
                    {
                        WebSocketReceiveResult rcvResult = await socket.ReceiveAsync(rcvBuffer, cts.Token);
                        byte[] msgBytes = rcvBuffer.Skip(rcvBuffer.Offset).Take(rcvResult.Count).ToArray();
                        string rcvMsg = Encoding.UTF8.GetString(msgBytes);
                        Console.WriteLine("Received: {0}", rcvMsg);
                    }
                }, cts.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
        }
        catch(Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
0

There are 0 best solutions below