zeromq / netmq

A 100% native C# implementation of ZeroMQ for .NET
Other
2.95k stars 744 forks source link

Unity NetMQ issue on iOS #937

Closed RossMelbourne closed 4 years ago

RossMelbourne commented 4 years ago

I have been using NetMQ with Unity successfully on Win10 and Mac OS. When I run the same code (below) on an iPhone XR via xCode I am getting some kind of socket error. Is there a setting in plist in xCode I need to set?

Environment

NetMQ Version:    4 (I think)
Operating System: iOS 13.7
.NET Version:     4.x

Expected behaviour

SendFrame works on Windows 10 and Mac OS with no issues

Actual behaviour

On iOS SendFrame receives the following exception:

NetMQException: Exception of type 'NetMQ.NetMQException' was thrown. at NetMQ.Core.Transports.Tcp.TcpConnector.OutCompleted (System.Net.Sockets.SocketError socketError, System.Int32 bytesTransferred) [0x00000] in <00000000000000000000000000000000>:0 at NetMQ.Core.IOObject.OutCompleted (System.Net.Sockets.SocketError socketError, System.Int32 bytesTransferred) [0x00000] in <00000000000000000000000000000000>:0 at NetMQ.Core.Utils.Proactor.Loop () [0x00000] in <00000000000000000000000000000000>:0 at System.Threading.ThreadHelper.ThreadStart_Context (System.Object state) [0x00000] in <00000000000000000000000000000000>:0 at System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) [0x00000] in <00000000000000000000000000000000>:0 at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) [0x00000] in <00000000000000000000000000000000>:0 at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state) [0x00000] in <00000000000000000000000000000000>:0 at System.Threading.ThreadHelper.ThreadStart () [0x00000] in <00000000000000000000000000000000>:0 UnityEngine.DebugLogHandler:LogException(Exception, Object) UnityEngine.Logger:LogException(Exception, Object) UnityEngine.Debug:LogException(Exception) UnityEngine.UnhandledExceptionHandler:PrintException(String, Exception) UnityEngine.UnhandledExceptionHandler:HandleUnhandledException(Object, UnhandledExceptionEventArgs)

Steps to reproduce the behaviour

I am using the code from https://github.com/Sohojoe/UnityMQ (freezing has been resolved).

My code: protected override void Run() { ForceDotNet.Force(); // this line is needed to prevent unity freeze after one use, not sure why yet using (RequestSocket client = new RequestSocket()) { client.Connect(Global.mobile2RobotConnectionStr);

        while (Running)
        {
            messageToSendToRobot = "Test";

            if (messageToSendToRobot != "")
            {
                try
                {
                    client.SendFrame(messageToSendToRobot);
                }
                catch (TerminatingException me)
                {
                    Debug.Log("TerminatingException: " + me);
                    client.Dispose();
                    Debug.Log("Failed to send message to Robot: " + messageToSendToRobot);
                    break;
                }

                // ReceiveFrameString() blocks the thread until you receive the string, but TryReceiveFrameString()
                // do not block the thread, you can try commenting one and see what the other does, try to reason why
                // unity freezes when you use ReceiveFrameString() and play and stop the scene without running the server
                //                string message = client.ReceiveFrameString();
                //                Debug.Log("Received: " + message);
                string message = null;
                bool gotMessage = false;
                while (Running)
                {
                    try
                    {
                        gotMessage = client.TryReceiveFrameString(out message); // this returns true if it's successful
                        if (gotMessage) break;
                    }
                    catch (TerminatingException me)
                    {
                        client.Dispose();
                        Debug.Log("Failed to get response from Robot for message: " + messageToSendToRobot);

                        break;
                    }

                }

                if (gotMessage)
                {
                   // Debug.Log("Mobile Received this from Robot " + message);

                    if(message == Global.mobile2RobotCommReady)
                    {
                        Global.mobile2RobotCommReadyNow = true;
                        Debug.Log("Robot is Ready for Communications");
                        messageToSendToRobot = "";
                    }
                    else
                    {
                        commClient.RobotCommFeedback(message);
                        messageToSendToRobot = "";
                    }
                }
            }
        }
    }
    Debug.Log("after Running");
    NetMQConfig.Cleanup(); // this line is needed to prevent unity freeze after one use, not sure why yet
}
RossMelbourne commented 4 years ago

NetMQ does work on iOS! I rebuilt my project to run in the iOS simulator and it worked. So then I tried again on my iPhone and this time it worked. I really am not sure what changed to make this work but it does.