WebSocketClient ReceiveAsync никогда не завершается (Mono, Linux) - PullRequest
1 голос
/ 04 июля 2019

У меня проблемы с WebSockets на Mono, Linux, ARM (на всякий случай это Jetson Nano).

Этот пример подключается к серверу WebSocket, а затем ожидает первого текстового сообщения, которое возвращается, регистрирует его и все. Эта программа корректно работает под Windows. Но когда я запускаю его на Nano (ARM Linux Ubuntu, Mono, Framework v4.6.1), он никогда не получает сообщение. Он подключается и выдает ReceiveAsync, но ReceiveAsync никогда не завершается.

Мой тестовый сервер WebSocket просто лает обратно «привет» текстовое сообщение сразу после подключения, и сервер работает правильно, потому что другие клиенты могут подключиться и получить сообщение привет правильно. Просто эта сборка C # Mono не работает.

Он использует wss (WebSockets через HTTPS), и сервер оказывается самозаверяющим сертификатом во время разработки, поэтому ServerCertificateValidationCallback возвращает значение true, чтобы разрешить его.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace WebSocketClientTest
{
    class Program
    {

        static ManualResetEvent exitEvent = null;

        static void HandleMessage(System.Net.WebSockets.WebSocketMessageType type, byte[] buffer, int count)
        {
            Console.WriteLine(string.Format("Received {0} message of {1} bytes", type.ToString(), count));
            if (type == WebSocketMessageType.Text)
            {
                string text = Encoding.UTF8.GetString(buffer, 0, count);
                Console.WriteLine(text);
                exitEvent.Set();
            }
        }

        static void Main(string[] args)
        {
            ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(delegate { return true; });
            exitEvent = new ManualResetEvent(false);
            var webSocket = new ClientWebSocket();
            string uri = "wss://localhost:8333/api/ws";
            Console.WriteLine("Connecting to {0}", uri);
            try
            {
                webSocket.ConnectAsync(new Uri(uri), CancellationToken.None).GetAwaiter().GetResult();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return;
            }
            Console.WriteLine("Connected");
            Action receive = null;
            receive = delegate
            {
                byte[] buffer = new byte[32768];
                webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None).ContinueWith(t =>
                {
                    if (t.IsFaulted)
                    {
                        Console.WriteLine("Receive fault.");
                        return;
                    }
                    if (t.IsCanceled)
                    {
                        Console.WriteLine("Cancel fault.");
                        return;
                    }
                    HandleMessage(t.Result.MessageType, buffer, t.Result.Count);

                    receive();
                });
            };
            receive();

            exitEvent.WaitOne();
        }
    }
}

Я собрал эту программу, запустив xbuild.

Джетсон Нано; Linux 4.9.140-tegra aarch64; моно 4.6.2;

...