C# 使用Socket IO在Unity中执行UI相关操作的正确方法是什么

C# 使用Socket IO在Unity中执行UI相关操作的正确方法是什么,c#,unity3d,socket.io,C#,Unity3d,Socket.io,我已经使用socket io几个月了。在unity中实现socket时,我遇到了很多问题。但我的主要问题是,当我从套接字连接接收消息/数据时,我不能仅仅调用一个方法来执行一些与UI相关的操作。我想出了一个布尔变量,当bool为true时执行特定的操作,并在Update()中执行一些我觉得不是有效的方法 例如: public GameObject IdleGo; bool isDone = false; Socket socket; // Start is called before the f

我已经使用socket io几个月了。在unity中实现socket时,我遇到了很多问题。但我的主要问题是,当我从套接字连接接收消息/数据时,我不能仅仅调用一个方法来执行一些与UI相关的操作。我想出了一个布尔变量,当bool为true时执行特定的操作,并在
Update()
中执行一些我觉得不是有效的方法

例如:

public GameObject IdleGo;
bool isDone = false;
Socket socket;

// Start is called before the first frame update
void Start()
{
   InitSocket();
}

// Update is called once per frame
void Update()
{
    if(isDone)
    {
        isDone = false;
        IdleGo.SetActive(true);
    }
}

void InitSocket()
{
    if (socket == null)
    {
        socket = IO.Socket(ServerURL);
        socket.On(Socket.EVENT_CONNECT, () =>
        {
            Debug.Log("connecting..");

            socket.On("response", (data) =>
            {
                Debug.Log("response: " + data);
                
                if (data == "connected")
                {
                    isDone = true;
                }
            });
        });
    }
}
我很想知道socket的整个过程是如何与Unity一起完成的,因为我将在不久的将来制作一个多人游戏


谢谢。

我会将整个套接字移动到后台线程,以避免任何阻塞

为了在Unity主线程中等待结果,使用
Update
bool
标志是可以的,但我通常使用

public GameObject IdleGo;

private Socket socket;

// A thread-safe queue for passing a callback into the next Update call
private readonly ConcurrentQueue<Action> _mainThreadhActions = new ConcurrentQueue<Action>();

// Yes! You can make Start return IEnumerator
// In this case Unity automatically starts it as a Coroutine instead
private IEnumerator Start()
{
    // Create a new thread in order to run the InitSocketThread method
    var thread = new Thread(InitSocketThread);
    // start the thread
    thread.Start();

    // Wait until a callback action is added to the queue
    yield return new WaitUntil(() => _mainThreadhActions.Count > 0);

    // If this fails something is wrong ^^
    // simply get the first added callback
    if(!_mainThreadhActions.TryDequeue(out var action))
    {
        Debug.LogError("Whoops something went wrong!", this);
        yield break;
    }
    
    // Execute the code of the added callback
    action?.Invoke();
}

void InitSocketThread()
{
    if (socket == null)
    {
        socket = IO.Socket(ServerURL);
        socket.On(Socket.EVENT_CONNECT, () =>
        {
            Debug.Log("connecting..");

            socket.On("response", (data) =>
            {
                // Simply wrap your main thread code by wrapping it in a lambda expression
                // which is enqueued to the thread-safe queue
                _mainThreadhActions.Enqueue(()=>
                {
                    // This will be executed after the next Update call

                    Debug.Log("response: " + data);
                
                    if (data == "connected")
                    {
                        IdleGo.SetActive(true);
                    }
                }
            });
        });
    }
}
公共游戏对象IdleGo;
专用插座;
//用于将回调传递到下一个更新调用的线程安全队列
私有只读ConcurrentQueue_mainThreadhActions=new ConcurrentQueue();
//对!!您可以使开始返回IEnumerator
//在这种情况下,Unity会自动将其作为协同程序启动
私有IEnumerator Start()
{
//创建一个新线程以运行InitSocketThread方法
var thread=新线程(InitSocketThread);
//开线
thread.Start();
//等待回调操作添加到队列中
返回新的等待时间(()=>_mainThreadhActions.Count>0);
//如果失败了,就有问题了^^
//只需获取第一个添加的回调
if(!\u mainThreadhActions.TryDequeue(out var action))
{
LogError(“哎呀,出问题了!”,这个);
屈服断裂;
}
//执行添加的回调函数的代码
action?.Invoke();
}
void InitSocketThread()
{
if(套接字==null)
{
socket=IO.socket(ServerURL);
socket.On(socket.EVENT_CONNECT,()=>
{
Debug.Log(“连接…”);
socket.On(“响应”,(数据)=>
{
//只需将主线程代码包装在lambda表达式中即可
//将其排入线程安全队列
_mainThreadhActions.Enqueue(()=>
{
//这将在下一次更新调用后执行
Log(“响应:+数据”);
如果(数据==“已连接”)
{
IdleGo.SetActive(true);
}
}
});
});
}
}

你应该独立于UI线程执行cpu/io/网络绑定操作,在这里同步调用update会导致UI响应差这是一种方法,但实际上你应该喜欢将整个套接字代码放入一个线程/任务中,这样就不会导致任何冻结。我不知道为什么它会被否决,因为我似乎找不到n回答。stackoverflow中已经有一些常见的问题,它们是最热门的问题,也是投票最多的问题。@derHugo谢谢你的建议。你能告诉我如何在unity中安全地做到这一点吗?谢谢@derHugo。我会尝试一下,并让你知道。