ZeroMQ不在Unity中工作,但作为控制台应用程序工作

2024-06-26 00:10:08 发布

您现在位置:Python中文网/ 问答频道 /正文

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

import zmq

context = zmq.Context()
socket = context.socket(zmq.PAIR)
socket.bind(f"tcp://*:5556")

socket.send(b"Server message to client")
print("Sent")

我有一个MonoBehaviour脚本连接到Unity中的一个游戏对象,它看起来像这样:

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

这个游戏永远挂在ReceiveFrameString()上,破坏了团结。另外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}");
        }
    }
}

这个应用程序工作得很好

我怎样才能解决这个问题


Tags: py脚本游戏消息servervarcontextmsg
2条回答

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

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

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

读取各种线程,https://forum.unity.com/threads/solved-multiplayer-networking-lan-wont-connect-from-another-pc.470459/

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

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

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

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

Server doesn't do anything when a connection is made. The server is a slave and waits for a client to send a command. [...] It behaves differently as console application, because you are dealing with a different kernel/operating system with different drivers.

server.SendFrameEmpty();添加到客户端和socket.recv()添加到服务器可以解决问题,但Unity仍然冻结

我发现this answer说:

The key is to have AsyncIO.ForceDotNet.Force(); before you start and NetMQConfig.Cleanup(); before you end.

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

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

相关问题 更多 >