【问题标题】:Signalr MessagePack .net core 3 and UWP AppSignalr MessagePack .net core 3 和 UWP App
【发布时间】:2019-09-07 04:42:23
【问题描述】:

我无法在 UWP 客户端上使用 Signalr MessagePack。 我在 .net 核心客户端 3 WPF 上使用了此代码,但在 UWP 上我无法使用它。 我如何还可以使用 UWP Signarl MessagePack 并使用 Dispatcher.Invoke? 感谢那些能够帮助我的人。

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

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

                });
            });

            connection.StartAsync();

【问题讨论】:

  • 在我的回答中添加了更多内容...

标签: asp.net-core .net-core uwp signalr


【解决方案1】:

感谢您的建议。 与此同时,我已经看到我正在等待对使用 UWP 调度程序的响应,但问题是我无法连接到服务器。 我不知道为什么连接状态总是断开连接。 在 WPF / 控制台客户端上它工作正常,它连接并接收消息。

使用 UWP 甚至无法连接!

感谢您的帮助。

这是我的代码:

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);
        }

    }

【讨论】:

    【解决方案2】:

    我注意到提琴手从控制台客户端.net core 和 UWP 客户端连接时的区别在于,与客户端控制台.net core 的连接设置了用户代理和 HTTP/1.1

    此客户端 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
    
    

    这个客户端.net核心:

    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
    
    

    【讨论】:

      【解决方案3】:

      你添加了这个包吗?

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

      另外,要进入 UI 线程,最好使用的调度程序是这样的:

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

      (来自这个 SO 问题:Correct way to get the CoreDispatcher in a Windows Store app)

      使用 MessagePack 没有什么神奇之处。使用 MessagePack 的唯一优势是您可以使用比 JSON 文本更少的带宽。但是,当您尝试解决问题时,调试起来会更加困难。

      我建议您在开发应用程序时使用 JSON 协议...然后您可以使用 Fiddler 读取在您的服务器和应用程序之间来回传输的所有 JSON SignalR 消息。最后切换到 MessagePack。

      ** 引用另一个答案中提供的代码 **

      我认为您不太了解如何使用 async/await。在您的页面构造函数中,您的 StartAsync 方法实际上是异步的。基本上,此调用将启动您的 SignalR 连接,但在连接开始完成之前继续进行。这意味着检查连接的状态仍然会被断开......并且试图在该连接上发送任何东西都行不通。您也不能等待构造函数中的任何内容。相反,将大部分内容移至 OnNavigatedTo 覆盖方法。不过,您可以将连接的构建留在构造函数上。

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

      最后,除非您有充分的理由这样做,否则永远不要创建返回 void 的异步方法。如果它没有返回任何东西,那么至少让它返回Task。这样,当您调用它时,您实际上可以await 您的方法。 void 返回的异步方法是一种“即发即弃”的方法……如果你无法预料后果,它会让你头疼。

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

      现在,您可以像这样调用此方法:await JoinGroupAsync() (方法名称末尾的“Async”只是约定。不是必需的。)

      【讨论】:

      • 仅供参考,您应该只是编辑您的问题以添加相关详细信息,而不是创建自己的答案...
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-20
      • 1970-01-01
      • 2021-12-06
      相关资源
      最近更新 更多