WebSocketClient ReceiveAsync never completes (Mono, Linux)

393 Views Asked by At

I'm having trouble with WebSockets on Mono, Linux, ARM (it's a Jetson Nano, in case that matters).

This example connects to a WebSocket server and then waits for the first text message that comes back, logs it and that's it. This program works correctly under Windows. But when I run it on the Nano (ARM Linux Ubuntu, Mono, Framework v4.6.1) it never receives the message. It connects, and issues the ReceiveAsync, but the ReceiveAsync never completes.

My test WebSocket server just barks back a "hello" text message immediately upon connecting, and the server is working correctly because other clients can connect and receive the hello message correctly. It's just this C# Mono build that doesn't work.

It's using wss (WebSockets over HTTPS) and the server happens to be a self-signed certificate during development, hence the ServerCertificateValidationCallback returning true to allow it.

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

I built this program by running xbuild.

Jetson Nano; Linux 4.9.140-tegra aarch64; mono 4.6.2;

0

There are 0 best solutions below