You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity Netcode for GameObjects:主机断开连接检测方案咨询

主机断开连接检测(Netcode for GameObjects + Facepunch.Steamworks/FacepunchTransport)

我正在Unity中结合Facepunch.Steamworks与FacepunchTransport使用Netcode for GameObjects进行开发,需要实现主机检测自身断开连接的功能,以便将主机切回主菜单。

客户端检测主机断开的代码如下:

private void OnEnable() {
    NetworkManager.Singleton.OnClientDisconnectCallback += OnClientDisconnectCallback;
}

private void OnDisable() {
    NetworkManager.Singleton.OnClientDisconnectCallback -= OnClientDisconnectCallback;
}

private void OnClientDisconnectCallback(ulong id) {
    Debug.Log("OnClientDisconnectCallback: " + id.ToString());

    if (IsClient) {
        if (id == 0) { // 0 = host?!
            LobbySaver.instance.currentLobby?.Leave();
            LobbySaver.instance.currentLobby = null;
            NetworkManager.Singleton.Shutdown();

            SceneManager.LoadScene("MainMenu");
        }
    }
}

但OnClientDisconnectCallback回调不会在主机自身触发,无法看到对应的调试日志。因此有以下问题:

  1. 是否有更优的主机断开连接检测方式?
  2. 如何让主机自身感知到已断开连接?

问题解答

1. 更优的主机断开连接检测方式

针对FacepunchTransport + Steamworks的场景,推荐两种更可靠的检测逻辑:

  • 监听Steam底层网络状态:直接通过Facepunch.Steamworks的SteamClient或SteamNetworking模块检测连接状态,能精准捕捉网络层面的异常断开,比Netcode上层回调更及时。
  • 结合Netcode服务器回调:利用NetworkManager.Singleton.OnServerStopped回调,覆盖服务器主动关闭或异常终止的场景,同时搭配自定义心跳检测应对意外断开的边缘情况。

2. 让主机自身感知断开连接的实现方法

方法一:Steam原生连接状态检测

利用Facepunch.Steamworks提供的原生API,在主机端实时检测网络连接状态:

private void Update()
{
    if (!NetworkManager.Singleton.IsHost) return;

    // 检测Steam客户端是否处于连接状态
    if (!SteamClient.IsConnected)
    {
        HandleHostDisconnect();
    }
}

private void HandleHostDisconnect()
{
    // 清理Lobby资源
    LobbySaver.instance.currentLobby?.Leave();
    LobbySaver.instance.currentLobby = null;
    // 关闭Netcode服务
    NetworkManager.Singleton.Shutdown();
    // 切回主菜单
    SceneManager.LoadScene("MainMenu");
}

方法二:Netcode回调+自定义心跳检测

结合Netcode的服务器停止回调,加上定时心跳检测覆盖意外断开场景:

private void OnEnable()
{
    if (NetworkManager.Singleton != null)
    {
        NetworkManager.Singleton.OnServerStopped += OnServerStopped;
    }
}

private void OnDisable()
{
    if (NetworkManager.Singleton != null)
    {
        NetworkManager.Singleton.OnServerStopped -= OnServerStopped;
    }
}

private void OnServerStopped(bool isHost)
{
    // 仅在主机身份触发时处理
    if (isHost)
    {
        HandleHostDisconnect();
    }
}

// 自定义心跳检测,防止意外断开未触发回调
private float _heartbeatInterval = 5f;
private float _heartbeatTimer;
private void Update()
{
    if (!NetworkManager.Singleton.IsHost) return;

    _heartbeatTimer += Time.deltaTime;
    if (_heartbeatTimer >= _heartbeatInterval)
    {
        _heartbeatTimer = 0;
        // 双重检测:Netcode服务器状态 + Steam连接状态
        if (!NetworkManager.Singleton.IsServer || !SteamClient.IsConnected)
        {
            HandleHostDisconnect();
        }
    }
}

private void HandleHostDisconnect()
{
    LobbySaver.instance.currentLobby?.Leave();
    LobbySaver.instance.currentLobby = null;
    NetworkManager.Singleton.Shutdown();
    SceneManager.LoadScene("MainMenu");
}

关键注意点

  • 主机同时具备客户端和服务器身份,IsClient和IsServer均返回true,但OnClientDisconnectCallback仅在外部客户端断开时触发,不会针对主机自身的客户端实例触发。
  • 优先使用Steam原生检测,因为FacepunchTransport底层依赖Steam Networking,能更直接地捕捉网络异常,避免Netcode上层逻辑的延迟或遗漏。

内容的提问来源于stack exchange,提问作者Taki7o7

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 01:07:33