0

I can't use Signalr MessagePack on UWP client. I used this code on the .net core client 3 WPF but on UWP I can't use it. How can I also use UWP Signarl MessagePack and use Dispatcher.Invoke? Thanks to those who will be able to help me.

var connection = new HubConnectionBuilder()
                        .WithUrl("https://localhost:44368/messagehub")
                        .AddMessagePackProtocol()
                        .Build();

            connection.On<string, string>("ReceiveMessage", (title, message) =>
            {
                this.Dispatcher.Invoke(() =>
                {

                });
            });

            connection.StartAsync();

3 Answers3

0

Have you added this package?

Microsoft.AspNetCore.SignalR.Protocols.MessagePack https://www.nuget.org/packages/Microsoft.AspNetCore.SignalR.Protocols.MessagePack/3.0.0-preview9.19424.4

Also, to get to the UI thread, the best dispatcher to use is like this:

Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
() =>
{
    // Your UI update code goes here!
});

(from this SO question: Correct way to get the CoreDispatcher in a Windows Store app)

There's no magic to using MessagePack. The only advantage to using MessagePack is you might use less bandwidth than JSON text. However, it's harder to debug when you're trying to fix a problem.

I'd recommend you use JSON protocols while developing your app... then you can use Fiddler to read all of the JSON SignalR messages going back and forth between your server and app. Switch to MessagePack towards the end.

** Referring to code supplied in another answer **

I don't think you understand how to use async/await very well. In your page constructor, your StartAsync method is actually asynchronous. Basically, this call will start your SignalR connection, but then keep going before the connection start has finished. This means checking the state of the connection is still going to be disconnected... and trying to send anything out on that connection is not going to work. You also can't await anything in a constructor. Instead, move most of this to the OnNavigatedTo override method. You can leave the building of the connection on the constructor though.

protected async override void OnNavigatedTo(NavigationEventArgs e)
{
      await connection.StartAsync();
      // etc...
      base.OnNavigatedTo(e);
}

Finally, unless you have a good reason for doing so, never create an an asynchronous method that returns void. If it doesn't return anything, then at least make it return Task. That way, you can actually await your method when you call it. A void returning asynchronous method is a "fire-and-forget" method... which will cause you headaches if you can't anticipate the consequences.

public Task JoinGroupAsync()
        {
            return connection.InvokeAsync("JoinGroup", groupName);
        }

Now, you can call this method like this: await JoinGroupAsync() (The 'Async' on the end of the method name is just convention. It's not required.)

Lee McPherson
  • 931
  • 6
  • 20
0

thanks for the advice. I have already seen in the meantime that I was waiting for responses to using dispatchers with UWP but the problem is that I can't connect to the server. I don't know why the connection state is always on disconnected. While on WPF / Console client it works fine, it connects and receives the message.

With UWP it can't even connect!

Thanks for the help.

This is my code :

public sealed partial class MainPage : Page
    {
        public HubConnection connection { get; set; }
        public string groupName { get; set; }

        public MainPage()
        {
            this.InitializeComponent();

            connection = new HubConnectionBuilder()
                       .WithUrl("https://localhost:44368/messagehub")
                       .AddMessagePackProtocol()
                       .Build();
            connection.On<string, string>("ReceiveMessage", (title, message) =>
            {
                messagelist.Items.Add(string.Format("{0} {1}", title, message));
            });

            connection.StartAsync();
            messagelist.Items.Add(connection.State);

            groupName = "test";

            //JoinGroup();
        }

        public async void JoinGroup()
        {
            await connection.InvokeAsync("JoinGroup", groupName);
        }

    }
0

I noticed with the fiddler that the difference between when I connect from the console client .net core and UWP client is that the connection with the client console .net core has set the user agent and HTTP/1.1

this client UWP :

CONNECT localhost:44368 HTTP/1.0
Host: localhost:44368
Content-Length: 0
Connection: Keep-Alive
Pragma: no-cache

A SSLv3-compatible ClientHello handshake was found. Fiddler extracted the parameters below.

Version: 3.3 (TLS/1.2)
Random: 5D 71 63 8C 4B 15 ED ED 44 0E 6F 9B 57 E3 DB 19 96 43 5D CC 9C F4 E4 B6 DC 23 81 57 55 AE 5D 26
"Time": 20/08/2044 19:35:25
SessionID: empty
Extensions: 
    server_name localhost
    status_request  OCSP - Implicit Responder
    elliptic_curves unknown [0x1D), secp256r1 [0x17], secp384r1 [0x18]
    ec_point_formats    uncompressed [0x0]
    signature_algs  sha256_rsa, sha384_rsa, sha1_rsa, sha256_ecdsa, sha384_ecdsa, sha1_ecdsa, sha1_dsa, sha512_rsa, sha512_ecdsa
    SessionTicket   empty
    ALPN        h2, http/1.1
    extended_master_secret  empty
    0x0018      00 10 03 02 01 00
    renegotiation_info  00
Ciphers: 
    [C02C]  TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
    [C02B]  TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
    [C030]  TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
    [C02F]  TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
    [009F]  TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
    [009E]  TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
    [C024]  TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
    [C023]  TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
    [C028]  TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
    [C027]  TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
    [C00A]  TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
    [C009]  TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
    [C014]  TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA
    [C013]  TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA
    [009D]  TLS_RSA_WITH_AES_256_GCM_SHA384
    [009C]  TLS_RSA_WITH_AES_128_GCM_SHA256
    [003D]  TLS_RSA_WITH_AES_256_CBC_SHA256
    [003C]  TLS_RSA_WITH_AES_128_CBC_SHA256
    [0035]  TLS_RSA_AES_256_SHA
    [002F]  TLS_RSA_AES_128_SHA
    [000A]  SSL_RSA_WITH_3DES_EDE_SHA

Compression: 
    [00]    NO_COMPRESSION

this client .net core :

CONNECT localhost:44368 HTTP/1.1
Host: localhost:44368
User-Agent: Microsoft.AspNetCore.Http.Connections.Client/1.1.0-rtm-35687

A SSLv3-compatible ClientHello handshake was found. Fiddler extracted the parameters below.

Version: 3.3 (TLS/1.2)
Random: 5D 71 63 60 21 DE BF 7A D0 9E 35 AF 83 EB BD 7F 87 C0 0F 01 47 4A 97 3E 4B EB 3F E7 27 9D A6 84
"Time": 30/03/2021 20:43:41
SessionID: empty
Extensions: 
    server_name localhost
    elliptic_curves unknown [0x1D), secp256r1 [0x17], secp384r1 [0x18]
    ec_point_formats    uncompressed [0x0]
    signature_algs  sha256_rsa, sha384_rsa, sha1_rsa, sha256_ecdsa, sha384_ecdsa, sha1_ecdsa, sha1_dsa, sha512_rsa, sha512_ecdsa
    SessionTicket   empty
    extended_master_secret  empty
    renegotiation_info  00
Ciphers: 
    [C02C]  TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
    [C02B]  TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
    [C030]  TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
    [C02F]  TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
    [009F]  TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
    [009E]  TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
    [C024]  TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
    [C023]  TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
    [C028]  TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
    [C027]  TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
    [C00A]  TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
    [C009]  TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
    [C014]  TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA
    [C013]  TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA
    [009D]  TLS_RSA_WITH_AES_256_GCM_SHA384
    [009C]  TLS_RSA_WITH_AES_128_GCM_SHA256
    [003D]  TLS_RSA_WITH_AES_256_CBC_SHA256
    [003C]  TLS_RSA_WITH_AES_128_CBC_SHA256
    [0035]  TLS_RSA_AES_256_SHA
    [002F]  TLS_RSA_AES_128_SHA
    [000A]  SSL_RSA_WITH_3DES_EDE_SHA

Compression: 
    [00]    NO_COMPRESSION