itisnajim / SocketIOUnity

A Wrapper for socket.io-client-csharp to work with Unity.
MIT License
406 stars 69 forks source link

issues on Quest 2 headset #45

Closed wout-junius closed 1 year ago

wout-junius commented 1 year ago

When we run our socket IO connection on the Unity editor the connection perfecly works and we are connected. But when we build and run the exact same code to Android (Quest runs on Android) it does not connect. Strangly the server gets a get request when it tries to connects but no connection is made.

Wrapper code:

using Newtonsoft.Json;
using SocketIOClient;
using SocketIOClient.Newtonsoft.Json;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
using UnityEngine;

namespace Altheria.SocketIo
{

    /// <summary>
    /// Ah wrapping class to handle SocketIo systems of Altheria as a Device
    /// </summary>
    public class SocketIoHandeler
    {
        private static SocketIoHandeler instance = null;
        public static SocketIoHandeler Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new SocketIoHandeler();
                }
                return instance;
            }
        }

        /// <summary>
        /// Creates a connection to the websocket server using SocketIo standard.
        /// Registers the events to listen to.
        /// </summary>
        /// <param name="uri">The ip addres of the WebSockt Server</param>
        /// <param name="listeners">The Dictionary of event listener name and listener function</param>
        public void connect(Uri uri,Dictionary<string, Action<SocketIOResponse>> listeners)
        {
            connect(uri);
            RegisterMulipleSocketListener(listeners);
        }

        /// <summary>
        /// Creates a connection to the websocket server using SocketIo standard.
        /// </summary>s
        /// <param name="uri">The ip addres of the WebSockt Server</param>
        public void connect(Uri uri)
        {
            string deviceId = SystemInfo.deviceUniqueIdentifier;

            this.socket = new SocketIOUnity(uri);

            var jsonSerializer = new NewtonsoftJsonSerializer();
            socket.JsonSerializer = jsonSerializer;
            socket.OnConnected += async (sender, e) =>
            {
                await socket.EmitAsync("RegisterDevice", deviceId);
            };

            _ = socket.ConnectAsync();
            UnityEngine.Debug.Log(this.socket.Connected);
        }

        /// <summary>
        /// Registers an event Listener for the SocketServer
        /// </summary>
        /// <param name="listenerKey"> The name of the Socket event</param>
        /// <param name="listener">The function that executes when this event gets triggers</param>
        public void RegisterSocketListener(string listenerKey, Action<SocketIOResponse> listener)
        {
            this.socket.OnUnityThread(listenerKey, listener);
        }

        /// <summary>
        ///  Registers an dictionary of event Listeners for the SocketServer
        /// </summary>
        /// <param name="listeners">>The Dictionary of event listener name and listener function</param>
        public void RegisterMulipleSocketListener(Dictionary<string, Action<SocketIOResponse>> listeners)
        {
            foreach (var x in listeners)
            {
                RegisterSocketListener(x.Key, x.Value);
            }
        }

        public SocketIOUnity socket { get; set; }

        public string deviceId { get; set; }

        /// <summary>
        /// Emits an event to the websocket server
        /// </summary>
        /// <param name="eventName">The name of the event</param>
        /// <param name="data">The data to send to the server</param>
        public void Emit(string eventName, params object[] data )
        {
            this.socket.Emit(eventName, data);
        }

    }

}
itisnajim commented 1 year ago

I don't have a Quest 2 device to test, here is some suggestions for some potential solutions:

  1. Add the required permissions to the AndroidManifest.xml file to allow internet and network access. This can be done by adding the following lines:

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    You can refer to this Stack Overflow post for more information.

  2. In Unity, go to Edit -> Project Settings -> Player and select the Android platform. Then, navigate to the Build Settings and change the Internet Access setting from "Auto" to "Require".

  3. Check if the issue is related to the server or network setup. For example, try using the machine/server's IP address instead of "localhost", or check if there is any firewall or security settings on the network that might be blocking the connection. If so, try to allow the client's (Quest 2) IP address or MAC address.

  4. Review any error messages or logs for more information on the problem.

wout-junius commented 1 year ago

I fixed it by setting the build settings in unity in IL2CPP from Faster runtime to Faster (Smaller) builds. This caused the issue to disappear. probably some weird converting that happened in one but not the other.