jchristn/WatsonWebsocket

"Non-websocket request" in Unity

Opened this issue · 1 comments

Hello,

I want to implement a websocket server in unity with watson websocket. For this I built watson websocket for .Net Standard 2.1 and imported the dll to unity. Starting the websocket seems to work but as soon as I try to connect with a simple javascript client it says non-websocket request.

Server:

public class TuioWatsonServer : MonoBehaviour
    {
        private readonly WatsonWsServer _server = new();
        private readonly List<Guid> _connections = new();

        private void Awake()
        {
            _server.AcceptInvalidCertificates = true;
            _server.HttpHandler = HttpHandler;
            _server.Logger = Debug.Log;
            _server.Start();
        }

        private void OnEnable()
        {
            _server.ClientConnected += OnClientConnected;
            _server.ClientDisconnected += OnClientDisconnected;
            _server.MessageReceived += OnMessageReceived;
        }

        private void OnDisable()
        {
            _server.ClientConnected -= OnClientConnected;
            _server.ClientDisconnected -= OnClientDisconnected;
            _server.MessageReceived -= OnMessageReceived;
        }

        private void OnClientConnected(object sender, ConnectionEventArgs e)
        {
            _connections.Add(e.Client.Guid);
            Debug.Log($"Client connected: {e.Client}");
        }

        private void OnClientDisconnected(object sender, DisconnectionEventArgs e)
        {
            _connections.Remove(e.Client.Guid);
            Debug.Log($"Client disconnected: {e.Client}");
        }

        private void OnMessageReceived(object sender, MessageReceivedEventArgs e)
        {
            Debug.Log($"Message received from {e.Client} -> {Encoding.UTF8.GetString(e.Data)}");
        }

        

        static void HttpHandler(HttpListenerContext ctx)
        { 
            HttpListenerRequest req = ctx.Request;
            string contents = null;
            using (Stream stream = req.InputStream)
            {
                using (StreamReader readStream = new StreamReader(stream, Encoding.UTF8))
                {
                    contents = readStream.ReadToEnd();
                }
            }

            Debug.Log("Non-websocket request received for: " + req.HttpMethod.ToString() + " " + req.RawUrl);
            if (req.Headers != null && req.Headers.Count > 0)
            {
                Debug.Log("Headers:"); 
                var items = req.Headers.AllKeys.SelectMany(req.Headers.GetValues, (k, v) => new { key = k, value = v });
                foreach (var item in items)
                {
                    Debug.Log($"  {item.key}: {item.value}");
                }
            }

            if (!String.IsNullOrEmpty(contents))
            {
                Debug.Log("Request body:");
                Debug.Log(contents);
            }
        }

        private void OnDestroy()
        {
            _server.Dispose();
        }
    }

Output when connecting:
image

I tried the test.server project and it worked. So this seems to be a unity related problem. Maybe somebody had similar experiences and found a solution.

Did you ever get further on this? I found an issue, but I'm also stuck on this.

In WatsonWsServer.AcceptConnections, there's the following check:
if (!ctx.Request.IsWebSocketRequest)

This always returns false. I changed it to the following:
if( !ctx.Request.Headers["Connection"].Contains( "Upgrade" ) || !ctx.Request.Headers["Upgrade"].Contains( "websocket" ) )
which checks if the header "Connection" contains "Upgrade" and the header "Upgrade" contains "websocket" (two conditions for websocket requests).

I now get past the HTTP check.

Unforunately, it's now failing when trying to accept the web socket
WebSocketContext wsContext = await ctx.AcceptWebSocketAsync( null );
This line of code (at line 492) just hangs. So I assume there's something else wrong with this code.

I'm currently using a C library (wrapped in C#) and I'm trying to switch to this library. I'm using the same javascript/websocket code for both. My C library accepts connections, while this library doesn't. I'm kinda stuck too.