InvalidDataException in a UWP scenario with SignalR


Recently I’ve created my first UWP App — yes it’s 2022, and I should go a very different way, but unfortunately I needed a feature which only exists in UWP still (later I will describe more 😊). One task of that UWP App is to send small messages to subscribers. My decision to solve this feature is to use an Azure SignalR Service. It's great for real time communication between distributed clients around the world. Also, I’ve heard from colleagues in the tech community it’s simple and clear to implement it in any application.

So far so good, as we Germans say. 😂

My first step for realization was to read the documentations, which was quite nice described. I found samples how to implement a client-to-client communication with UWP. One client is the UWP app, the second is a console app running on a Raspberry Pi. That was not the problem. For establishing the connection … let me show you a picture, it makes it a bit better for understanding.

In the picture, you can see the current solution. The UWP App uses the SignalR Service directly. It’s because the App runs in a secure environment, so I can use the connection settings directly in the ServiceManagerBuilder component (from namespace Microsoft.Azure.SignalR.Management).


A few lines later, I create a hub with the ServiceManager.


The created hub allows me to send messages directly to the SignalR Service. That’s what I want, only sending, not receiving.


That was really simple, like the documentation and my colleagues mentioned.

Message Receiver

To receive the messages, the console app first has to negotiate to the SignalR service. Why? Why not go the same direct connection way? The simple answer is: The hub component does not contain a receiver method. That's it. 🤷‍♀️

To solve this “issue” in the console app I use the HubConnection component from Microsoft.AspNetCore.SignalR.Client namespace. These connections can receive messages, but before, I have to set up this connection.


The notificatrionUrlis the URL of the negotiation server (called “SignalR Negotiation” in the picture).

Negotiation Service

This service is just a simple web application running in a local environment, so my command line app can reach it. To establish the connection for my command line app, I prepared a Negotiation endpoint.

First, I need a ServiceHubContext. It's located in the Microsoft.Azure.SignalR.Management namespace too. In my solution, I use the StartAsync method of a hosted service in my web application. It's an interface to mark an internal service of a web application. By implementing the StartAsync method, you can prepare stuff in your web app before the app is handling requests in your endpoints.


The second step is to provide an endpoint for negotiation.


(Just for explanation, the _hubContext is the same instance as in the preparation before. It's injected in the constructor of my controller class)

This controller method negotiated a requester to use the SignalR service. After the negotiation, a client app is able to send and receive messages. It does not need the negotiation service anymore, except for the app has been restarted.

So, anything looks great. The SignalR Service is prepared in the cloud as a resource, my UWP app is able to send messages directly to this service, a negotiation web app enables clients to connect to the SignalR service too and finally my console line app is able to receive messages after a successful negotiation.

But here comes the big BUT.

How to solve the big BUT?

The first message transfers leaded to a few errors. Not in my code. In the SignalR library. I've got a lot of “System.IO.DataException in Microsoft.AspNetCore.SignalR.Protocols,Json.dll” prints in the Debug Window. But why? I send a message with two parameters of type string and expect to receive a message with two parameters of type string.

ATTENTION, in the screenshot you will find the solution already 😁

 

 


I think the reason for that misunderstanding of typed receiver described here is the intention to use (probably) a different sender. Maybe when I had used a HubConnection in my UWP app too, I think I had never seen the DataException. But as long as we can use the SignalR Service directly, we will run into this issue.

Hope it helpes you. 😉