Using Message Pack with ASP.NET Core SignalR

This post shows how SignalR could be used to send messages between different C# console clients using Message Pack as the protocol. An ASP.NET Core web application is used to host the SignalR Hub.

Code: https://github.com/damienbod/AspNetCoreAngularSignalR

Posts in this series

Setting up the Message Pack SignalR server

Add the Microsoft.AspNetCore.SignalR and the Microsoft.AspNetCore.SignalR.MsgPack NuGet packages to the ASP.NET Core server application where the SignalR Hub will be hosted. The Visual Studio NuGet Package Manager can be used for this.

Or just add it directly to the .csproj project file.

<PackageReference 
   Include="Microsoft.AspNetCore.SignalR" 
   Version="1.0.0-preview1-final" />
<PackageReference 
   Include="Microsoft.AspNetCore.SignalR.MsgPack" 
   Version="1.0.0-preview1-final" />

Setup a SignalR Hub as required. This is done by implementing the Hub class.

using Dtos;
using Microsoft.AspNetCore.SignalR;
using System.Threading.Tasks;

namespace AspNetCoreAngularSignalR.SignalRHubs
{
    // Send messages using Message Pack binary formatter
    public class LoopyMessageHub : Hub
    {
        public Task Send(MessageDto data)
        {
            return Clients.All.SendAsync("Send", data);
        }
    }
}

A DTO class is created to send the Message Pack messages. Notice that the class is a plain C# class with no Message Pack attributes, or properties.

using System;

namespace Dtos
{
    public class MessageDto
    {
        public Guid Id { get; set; }

        public string Name { get; set; }

        public int Amount { get; set; }
    }
}

Then add the Message Pack protocol to the SignalR service.

services.AddSignalR(options =>
{
	options.KeepAliveInterval = TimeSpan.FromSeconds(5);
})
.AddMessagePackProtocol();

And configure the SignalR Hub in the Startup class Configure method of the ASP.NET Core server application.

app.UseSignalR(routes =>
{
	routes.MapHub<LoopyMessageHub>("/loopymessage");
});

Setting up the Message Pack SignalR client

Add the Microsoft.AspNetCore.SignalR.Client and the Microsoft.AspNetCore.SignalR.Client.MsgPack NuGet packages to the SignalR client console application.

The packages are added to the project file.

<PackageReference  
   Include="Microsoft.AspNetCore.SignalR.Client" 
   Version="1.0.0-preview1-final" />
<PackageReference  
   Include="Microsoft.AspNetCore.SignalR.Client.MsgPack" 
   Version="1.0.0-preview1-final" />

Create a Hub client connection using the Message Pack Protocol. The Url must match the URL configuration on the server.

public static async Task SetupSignalRHubAsync()
{
 _hubConnection = new HubConnectionBuilder()
   .WithUrl("https://localhost:44324/loopymessage")
   .WithMessagePackProtocol()
   .WithConsoleLogger()
   .Build();

 await _hubConnection.StartAsync();
}

The Hub can then be used to send or receive SignalR messages using the Message Pack as the binary serializer.

using Dtos;
using Microsoft.AspNetCore.SignalR.Client;
using System;
using System.Threading.Tasks;

namespace ConsoleSignalRMessagePack
{
    class Program
    {
        private static HubConnection _hubConnection;

        public static void Main(string[] args) => MainAsync().GetAwaiter().GetResult();

        static async Task MainAsync()
        {
            await SetupSignalRHubAsync();
            _hubConnection.On<MessageDto>("Send", (message) =>
            {
                Console.WriteLine($"Received Message: {message.Name}");
            });
            Console.WriteLine("Connected to Hub");
            Console.WriteLine("Press ESC to stop");
            do
            {
                while (!Console.KeyAvailable)
                {
                    var message = Console.ReadLine();
                    await _hubConnection.SendAsync("Send", new MessageDto() { Id = Guid.NewGuid(), Name = message, Amount = 7 });
                    Console.WriteLine("SendAsync to Hub");
                }
            }
            while (Console.ReadKey(true).Key != ConsoleKey.Escape);

            await _hubConnection.DisposeAsync();
        }

        public static async Task SetupSignalRHubAsync()
        {
            _hubConnection = new HubConnectionBuilder()
                 .WithUrl("https://localhost:44324/loopymessage")
                 .WithMessagePackProtocol()
                 .WithConsoleLogger()
                 .Build();

            await _hubConnection.StartAsync();
        }
    }
}

Testing

Start the server application, and 2 console applications. Then you can send and receive SignalR messages, which use Message Pack as the protocol.


Links:

https://msgpack.org/

https://github.com/aspnet/SignalR

https://github.com/aspnet/SignalR#readme

https://radu-matei.com/blog/signalr-core/

Advertisements

7 comments

  1. […] Using Message Pack with ASP.NET Core SignalR | Software Engineering – Damien Bowden […]

  2. The big question remains, would you want to do this? How much longer does it take (with all the extra js needed) for the hub connection to be established? Is is faster than using json payloads? Can it compete with gzip content from controller methods? At least this is what I’d like to know 🙂

    1. Hi mortenmertner, yes correct, but depending on your payload, the message pack serializer payload is smaller, and faster so it makes sense for example with a backend service to service communication

      Greetings Damien

      1. Maybe. It only makes sense if it’s actually faster. Given that browsers deserialize JSON natively it is not a given that a binary format (which is decoded by JS) is faster. The only given is that it takes up fewer bytes on the wire. Performance benchmarks for large and small payloads are needed.

      2. yes, you are correct when the client is a browser app, but in this example, the client is a console application, or could be a second backend service, and then it would be faster.

        Greetings Damien

  3. Wael Emara · · Reply

    What is the message delivery reliability here, and how this compares against Akka.NET.

  4. […] Using message pack with ASP.NET Core SignalR […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s

%d bloggers like this: