<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Corrado Cavalli </title>
    <description>The latest articles on DEV Community by Corrado Cavalli  (@corcav).</description>
    <link>https://dev.to/corcav</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F129197%2Fd3039689-9f6e-408b-9b41-01eec3d50685.jpg</url>
      <title>DEV Community: Corrado Cavalli </title>
      <link>https://dev.to/corcav</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/corcav"/>
    <language>en</language>
    <item>
      <title>Using Azure Web PubSub with Protobuf subprotocol in .NET</title>
      <dc:creator>Corrado Cavalli </dc:creator>
      <pubDate>Thu, 27 Jul 2023 11:33:29 +0000</pubDate>
      <link>https://dev.to/corcav/using-azure-web-pubsub-with-protobuf-subprotocol-in-net-58li</link>
      <guid>https://dev.to/corcav/using-azure-web-pubsub-with-protobuf-subprotocol-in-net-58li</guid>
      <description>&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/azure/azure-web-pubsub/overview"&gt;Azure Web PubSub&lt;/a&gt; is a fully managed service that helps developers add real-time features using WebSockets and the publish-subscribe pattern.&lt;br&gt;
It supports the publish-subscribe messaging pattern and is scalable, reliable, and secure.&lt;br&gt;
Example of use are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Live dashboards and monitoring.&lt;/li&gt;
&lt;li&gt;Cross-platform live chat.&lt;/li&gt;
&lt;li&gt;Push instant notifications.&lt;/li&gt;
&lt;li&gt;Real-time broadcasting.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;An &lt;a href="https://azure.microsoft.com/free/dotnet/"&gt;Azure subscription&lt;/a&gt;.
&lt;/li&gt;
&lt;li&gt;An existing Web PubSub instance. &lt;a href="https://learn.microsoft.com/en-us/azure/azure-web-pubsub/howto-develop-create-instance?tabs=CLI&amp;amp;pivots=method-azure-portal"&gt;Create Web PubSub instance&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Getting started
&lt;/h3&gt;

&lt;p&gt;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 &lt;strong&gt;Keys&lt;/strong&gt; entry under &lt;strong&gt;Settings&lt;/strong&gt; on the left panel, scroll down the page to the &lt;strong&gt;client URL generator&lt;/strong&gt;, configure it and copy the the &lt;strong&gt;Client Access URL&lt;/strong&gt;.&lt;/p&gt;
&lt;h5&gt;
  
  
  Note
&lt;/h5&gt;

&lt;p&gt;For better and safer alternatives to generate the connection string, please refer to the &lt;a href="https://learn.microsoft.com/en-us/azure/azure-web-pubsub/howto-generate-client-access-url?tabs=javascript"&gt;official documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;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 (&lt;a href="https://learn.microsoft.com/en-us/azure/azure-web-pubsub/concept-client-protocols"&gt;example&lt;/a&gt;) but this is quite tedious and assumes a deep knowledge of the Web PubSub subprotocols.&lt;/p&gt;

&lt;p&gt;Fortunately, thank to &lt;a href="https://learn.microsoft.com/en-us/azure/azure-web-pubsub/quickstarts-pubsub-among-clients"&gt;dedicated SDKs&lt;/a&gt;, using the service does not require to deal with the subprotocols directly.&lt;/p&gt;
&lt;h3&gt;
  
  
  A simple .NET Core example
&lt;/h3&gt;

&lt;p&gt;Let's create a simple console application that connects to the Web PubSub service and sends a message to a group.&lt;/p&gt;

&lt;p&gt;1 - Create a new .NET Core console application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; dotnet new console
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2 - Add the &lt;a href="https://www.nuget.org/packages/Azure.Messaging.WebPubSub"&gt;Azure.Messaging.WebPubSub&lt;/a&gt; NuGet package to the project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet add package Azure.Messaging.WebPubSub.Client --prerelease
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3 - Add the following using statements to the &lt;code&gt;Program.cs&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Azure.Messaging.WebPubSub.Clients&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4 - Insert the following code in the &lt;code&gt;Main&lt;/code&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Group&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"protobuf-client-group"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Uri&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&amp;lt;your-connection-string&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;//Create the client&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;serviceClient&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WebPubSubClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Uri&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;//Subscribe to events&lt;/span&gt;
&lt;span class="n"&gt;serviceClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Connected&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Connected with connection id: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConnectionId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CompletedTask&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="n"&gt;serviceClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Disconnected&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Disconnected from connection id: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConnectionId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CompletedTask&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="n"&gt;serviceClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GroupMessageReceived&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Received text message: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CompletedTask&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;//Connects and join the group&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;serviceClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StartAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;serviceClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;JoinGroupAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Group&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Enter the message to send or just enter to stop"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadLine&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;//Send a message to the group&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsNullOrEmpty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;serviceClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SendToGroupAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Group&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BinaryData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;WebPubSubDataType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Disconnects and leave the group&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;serviceClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LeaveGroupAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Group&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;serviceClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StopAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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.&lt;/p&gt;

&lt;h3&gt;
  
  
  JSON vs Protobuf
&lt;/h3&gt;

&lt;p&gt;While being both data serialization protocols, as you can read &lt;a href="https://auth0.com/blog/beating-json-performance-with-protobuf/"&gt;here&lt;/a&gt;, Protobuf is around 5 times faster and around 33% the size of the same JSON message.&lt;br&gt;
Considering that the max size of a Web PubSub message is &lt;a href="https://learn.microsoft.com/en-us/azure/azure-web-pubsub/key-concepts"&gt;1 MB&lt;/a&gt; choosing Protobuf instead of JSON can be a winning choice in terms of speed and compactness of the messages exchanged.&lt;/p&gt;
&lt;h3&gt;
  
  
  Using the Protobuf subprotocol
&lt;/h3&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WebPubSubClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Uri&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;WebPubSubClientOptions&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Protocol&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WebPubSubJsonReliableProtocol&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But what if instead i want to use the &lt;code&gt;protobuf.webpubsub.azure.v1&lt;/code&gt; and &lt;code&gt;protobuf.reliable.webpubsub.azure.v1&lt;/code&gt; subprotocols supported by the Web PubSub?  &lt;/p&gt;

&lt;p&gt;Unfortunately the library does not support them out of the box but thank to this &lt;a href="https://www.nuget.org/packages/WebPubSub.Protobuf"&gt;NuGet package&lt;/a&gt; you can easily add support for them.   &lt;/p&gt;

&lt;h3&gt;
  
  
  Using the protobuf subprotocols
&lt;/h3&gt;

&lt;p&gt;1 - Add the &lt;a href="https://www.nuget.org/packages/Azure.Messaging.WebPubSub"&gt;WebPubSub.Protobuf&lt;/a&gt; NuGet package to the project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet add package WebPubSub.Protobuf --version 1.0.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2 - Add the following using statements to the &lt;code&gt;Program.cs&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;WebPubSub.Client.Protobuf&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3 - Add the protobuf subprotocol when creating the client&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WebPubSubClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;client-access-uri&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;WebPubSubClientOptions&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Protocol&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WebPubSubProtobufProtocol&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// or new WebPubSubProtobufReliableProtocol()&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4 - Run the application and see that it behaves exactly as before but now the messages are sent and received as protobuf messages.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sending custom Protobuf serialized messages
&lt;/h3&gt;

&lt;p&gt;The source code of the NuGet package is available &lt;a href="https://github.com/corradocavalli/WebPubSub.Protobuf"&gt;here&lt;/a&gt; and it includes a sample that shows how to send and receive messages serialized in &lt;code&gt;Text&lt;/code&gt;, &lt;code&gt;JSON&lt;/code&gt;, &lt;code&gt;Binary&lt;/code&gt; and &lt;code&gt;Protobuf&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://azure.microsoft.com/en-us/services/web-pubsub/"&gt;Web PubSub service&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/en-us/azure/azure-web-pubsub/overview"&gt;Web PubSub service documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/en-us/azure/azure-web-pubsub/concept-client-protocols"&gt;Web PubSub service client protocols&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/en-us/azure/azure-web-pubsub/quickstarts-pubsub-among-clients"&gt;Web PubSub service client SDKs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Azure/azure-sdk-for-net/tree/Azure.Messaging.WebPubSub_1.3.0/sdk/webpubsub/Azure.Messaging.WebPubSub.Client"&gt;Web PubSub service client SDK for .NET&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/aspnet/core/grpc/protobuf?view=aspnetcore-6.0"&gt;Create Protobuf messages for .NET apps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://chromium.googlesource.com/external/github.com/grpc/grpc/+/HEAD/src/csharp/BUILD-INTEGRATION.md"&gt;Protocol Buffers/gRPC Codegen Integration Into .NET Build&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>azure</category>
      <category>webpubsub</category>
      <category>protobuf</category>
      <category>csharp</category>
    </item>
    <item>
      <title>.NET Standard and Multi-targeting</title>
      <dc:creator>Corrado Cavalli </dc:creator>
      <pubDate>Wed, 16 Jan 2019 06:47:29 +0000</pubDate>
      <link>https://dev.to/corcav/net-standard-and-multi-targeting-2o0i</link>
      <guid>https://dev.to/corcav/net-standard-and-multi-targeting-2o0i</guid>
      <description>&lt;p&gt;I've recently blogged about multitargeting in .NET Standard libraries, what do you think? (dont' shoot the pianist... 😊)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/corrado-cavalli/net-standard-and-multi-targeting-e96920b3fcfe"&gt;link to blog post here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>netstandard</category>
      <category>dotnet</category>
      <category>visualstudio</category>
      <category>xamarin</category>
    </item>
  </channel>
</rss>
