Using Azure Web PubSub with Protobuf subprotocol in .NET

corcav

Corrado Cavalli

Posted on July 27, 2023

Using Azure Web PubSub with Protobuf subprotocol in .NET

Azure Web PubSub is a fully managed service that helps developers add real-time features using WebSockets and the publish-subscribe pattern.
It supports the publish-subscribe messaging pattern and is scalable, reliable, and secure.
Example of use are:

  • Live dashboards and monitoring.
  • Cross-platform live chat.
  • Push instant notifications.
  • Real-time broadcasting.

Prerequisites

Getting started

In order to connect to the Web PubSub service, you need to generate a connection string, the easiest way is to use the Azure portal, navigate to your Web PubSub instance, select the Keys entry under Settings on the left panel, scroll down the page to the client URL generator, configure it and copy the the Client Access URL.

Note

For better and safer alternatives to generate the connection string, please refer to the official documentation.

From this point on all you need to communicate with the Web PubSub service is to open a websocket connection to the generated URL and send/receive messages using the proper subprotocol (example) but this is quite tedious and assumes a deep knowledge of the Web PubSub subprotocols.

Fortunately, thank to dedicated SDKs, using the service does not require to deal with the subprotocols directly.

A simple .NET Core example

Let's create a simple console application that connects to the Web PubSub service and sends a message to a group.

1 - Create a new .NET Core console application.

 dotnet new console
Enter fullscreen mode Exit fullscreen mode

2 - Add the Azure.Messaging.WebPubSub NuGet package to the project.

dotnet add package Azure.Messaging.WebPubSub.Client --prerelease
Enter fullscreen mode Exit fullscreen mode

3 - Add the following using statements to the Program.cs file.

using Azure.Messaging.WebPubSub.Clients;
Enter fullscreen mode Exit fullscreen mode

4 - Insert the following code in the Main method.

const string Group = "protobuf-client-group";
const string Uri = "<your-connection-string>";

//Create the client
var serviceClient = new WebPubSubClient(new Uri(Uri));

//Subscribe to events
serviceClient.Connected += (arg) =>
{
    Console.WriteLine($"Connected with connection id: {arg.ConnectionId}");
    return Task.CompletedTask;
};
serviceClient.Disconnected += (arg) =>
{
    Console.WriteLine($"Disconnected from connection id: {arg.ConnectionId}");
    return Task.CompletedTask;
};

serviceClient.GroupMessageReceived += (arg) =>
{
    Console.WriteLine($"Received text message: {arg.Message.Data}");
    return Task.CompletedTask;
};

//Connects and join the group
await serviceClient.StartAsync();
await serviceClient.JoinGroupAsync(Group);

while (true)
{
    Console.WriteLine("Enter the message to send or just enter to stop");
    var message = Console.ReadLine();

    //Send a message to the group
    if (!string.IsNullOrEmpty(message))
    {
        await serviceClient.SendToGroupAsync(Group, BinaryData.FromString(message), WebPubSubDataType.Text);
    }
    else
    {
        // Disconnects and leave the group
        await serviceClient.LeaveGroupAsync(Group);
        await serviceClient.StopAsync();
        break;
    }
}
Enter fullscreen mode Exit fullscreen mode

5 - Run the application and enter a message to send to the group, you should see the message echoed back, you can also run more instances of the application to see the messages broadcasted to all the clients in the group.

JSON vs Protobuf

While being both data serialization protocols, as you can read here, Protobuf is around 5 times faster and around 33% the size of the same JSON message.
Considering that the max size of a Web PubSub message is 1 MB choosing Protobuf instead of JSON can be a winning choice in terms of speed and compactness of the messages exchanged.

Using the Protobuf subprotocol

This previous example uses the json.webpubsub.azure.v1 subprotocol meaning that all the messages are sent and received as JSON objects, in case of binary data it gets encoded as base64 string.
The library also supports the json.reliable.webpubsub.azure.v1 subprotocol, to use it all you need to do is to specify the subprotocol when creating the client:

var client = new WebPubSubClient(new Uri(Uri), new WebPubSubClientOptions
{
    Protocol = new WebPubSubJsonReliableProtocol()
});
Enter fullscreen mode Exit fullscreen mode

But what if instead i want to use the protobuf.webpubsub.azure.v1 and protobuf.reliable.webpubsub.azure.v1 subprotocols supported by the Web PubSub?

Unfortunately the library does not support them out of the box but thank to this NuGet package you can easily add support for them.

Using the protobuf subprotocols

1 - Add the WebPubSub.Protobuf NuGet package to the project

dotnet add package WebPubSub.Protobuf --version 1.0.0
Enter fullscreen mode Exit fullscreen mode

2 - Add the following using statements to the Program.cs file

using WebPubSub.Client.Protobuf
Enter fullscreen mode Exit fullscreen mode

3 - Add the protobuf subprotocol when creating the client


var client = new WebPubSubClient(new Uri("<client-access-uri>"), new WebPubSubClientOptions
{
    Protocol = new WebPubSubProtobufProtocol() // or new WebPubSubProtobufReliableProtocol()
});
Enter fullscreen mode Exit fullscreen mode

4 - Run the application and see that it behaves exactly as before but now the messages are sent and received as protobuf messages.

Sending custom Protobuf serialized messages

The source code of the NuGet package is available here and it includes a sample that shows how to send and receive messages serialized in Text, JSON, Binary and Protobuf.

References

💖 💪 🙅 🚩
corcav
Corrado Cavalli

Posted on July 27, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related