Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python ZeroMQ不';它不能在Unity中工作,但可以作为控制台应用程序工作_Python_C#_Unity3d_Zeromq - Fatal编程技术网

Python ZeroMQ不';它不能在Unity中工作,但可以作为控制台应用程序工作

Python ZeroMQ不';它不能在Unity中工作,但可以作为控制台应用程序工作,python,c#,unity3d,zeromq,Python,C#,Unity3d,Zeromq,我试图通过ZeroMQ将python进程与Unity游戏连接起来。我有一个python脚本server.py,它通过pair套接字发送消息 导入zmq context=zmq.context() socket=context.socket(zmq.PAIR) socket.bind(f“tcp://*:5556”) socket.send(b“服务器消息到客户端”) 打印(“已发送”) 我有一个monobhavior脚本连接到Unity中的一个游戏对象,看起来像这样: public class

我试图通过ZeroMQ将python进程与Unity游戏连接起来。我有一个python脚本
server.py
,它通过pair套接字发送消息

导入zmq
context=zmq.context()
socket=context.socket(zmq.PAIR)
socket.bind(f“tcp://*:5556”)
socket.send(b“服务器消息到客户端”)
打印(“已发送”)
我有一个
monobhavior
脚本连接到Unity中的一个游戏对象,看起来像这样:

public class AiManager : MonoBehaviour
{
    void Start()
    {
        using (var server = new PairSocket())
        {
            server.Connect("tcp://localhost:5556");
            var msg = server.ReceiveFrameString();
            Debug.Log(msg);
        }
    }
}
游戏将永远挂起并崩溃Unity。另外,
server.py
挂起并且不发送消息

但是,我创建了一个独立的控制台应用程序,代码完全相同:

class Program
{
    static void Main(string[] args)
    {
        using (var server = new PairSocket())
        {
            server.Connect("tcp://localhost:5556");
            var msg = server.ReceiveFrameString();
            Console.WriteLine($"From Server: {msg}");
        }
    }
}
这个应用程序工作得很好


我该如何解决这个问题呢?

它可以是一个完整的PITA,确保Unity(即Unity应用程序)只拥有本地通话的权限

我假设你是在PC机上,而不是Mac机上,仔细检查Unity是否被允许进行这种网络连接

Windows防火墙设置可以是Unity的总PITA

阅读各种线索

一个解决方案是,在AWS上启动一个真正的远程服务器,并尝试一下!这通常比让localhost工作更容易


一个糟糕的问题是,很简单,在某些版本的Windows上,出现在Unity、doh后面的愚蠢的“OK”对话框可能会浪费数小时。

好吧,经过数小时的试验和浏览互联网,我已经解决了这个问题

感谢@jdweng的评论,首先要做的是从客户端向服务器发送一条消息

建立连接时,服务器不执行任何操作。服务器是从服务器,等待客户端发送命令。[…]它的行为与控制台应用程序不同,因为您处理的是具有不同驱动程序的不同内核/操作系统

添加一个
server.SendFrameEmpty()
到客户端,socket.recv()到服务器解决了问题,但Unity仍然冻结

我发现他在说:

关键是要有
AsyncIO.ForceDotNet.Force()在启动和
NetMQConfig.Cleanup()之前在结束之前

最后,整个工作代码如下所示

public class AiManager : MonoBehaviour
{
    void Start()
    {
        AsyncIO.ForceDotNet.Force();
        using (var server = new PairSocket())
        {
            server.Connect("tcp://localhost:5556");
            server.SendFrameEmpty();
            var msg = server.ReceiveFrameString();
            Debug.Log(msg);
        }
        NetMQConfig.Cleanup();
    }
}

你是说该方法的阻塞时间比你预期的要长,还是说你根本没料到它会阻塞?当控制台应用程序立即工作时,该方法将永远阻塞(在我手动终止进程之前5分钟以上),并在收到消息之前发送消息。当建立连接时,服务器通常不会发回消息。在收到回复之前,您必须至少发送一份报税表。@jdweng有效!在从服务器发送到客户机之前,先从客户机发送到服务器可以解决这个问题。如果你能在回答中解释为什么它可以工作,为什么在控制台应用程序中不需要它,我会很高兴地接受它。一般来说,控制台应用程序的巨大区别在于,在控制台中,你不在乎线程是否冻结一段时间,直到有响应为止。。。在Unity中,基于帧的应用程序还将冻结您的主线程和整个Unity编辑器,直到出现响应->使用线程或任务