Colyseus的几个使用问题

  1. Colyseus的断线重连需要开发者自己实现吗?比如某个用户因为网络抖动/关闭网络导致用户退出了房间,此时客户端会主动一直尝试重连吗?

  2. Colyseus会有心跳机制维持websocket不被nginx主动断开吗?印象中如果websocket超过一定时间(一般默认是60s)没有通信则主动断开此websocket,之前我们会保证60s内一定会有websocket通信达到不被断开的目的。

麻烦大佬有空帮忙解答下哈,万分感谢!

呼, 终于又能上网了.
抱歉由于封城原因有点耽误了.
WebSocket是类似Socket的TCP长连接通讯模式. 应该不会被随便断开.
其他问题等我问问开发组, 然后尽快给出答复!

@wuyongquan
总结整理如下:
先说断线: 客户端断线可能性有很多, 比如死机, 闪退, 用户强制退出, 断网, 用户正常退出等等. 对于每种情况, 需要对应的使用操作系统SDK, 游戏引擎SDK, Colyseus SDK 针对不同的事件或者错误进行不同的处理.
以下代码选取自 Colyseus 官方 Unity SDK Example.

    private void OnLeaveRoom(int code)
    {
        WebSocketCloseCode parsedCode = WebSocketHelpers.ParseCloseCodeEnum(code);
        LSLog.Log(string.Format("ROOM: ON LEAVE =- Reason: {0} ({1})", parsedCode, code));
        _pingThread.Abort();
        _pingThread = null;
        _room = null;

        if (parsedCode != WebSocketCloseCode.Normal && !string.IsNullOrEmpty(_lastRoomId))
        {
            JoinRoomId(_lastRoomId,null);
        }
    }

注意各种事件和回调函数是由各种SDK自动发送或调用的, 但是对于这些事件的处理不是自动的, 需要程序员自己设计逻辑.

再说重连: 重连的意义在于恢复 RoomID 与 SessionID. 为此 Colyseus 客户端 SDK 提供了 reconnect 函数.
同时 Colyseus 服务端 提供了 allowReconnection 函数, 允许离线的客户端在指定时间内重连 (恢复 RoomID 与 SessionID).
以下代码出自 Colyseus API:
Server:

async onLeave (client: Client, consented: boolean) {
  // flag client as inactive for other users
  this.state.players.get(client.sessionId).connected = false;

  try {
    if (consented) {
        throw new Error("consented leave");
    }

    // allow disconnected client to reconnect into this room until 20 seconds
    await this.allowReconnection(client, 20);

    // client returned! let's re-activate it.
    this.state.players.get(client.sessionId).connected = true;

  } catch (e) {

    // 20 seconds expired. let's remove the client.
    this.state.players.delete(client.sessionId);
  }
}

Client:

try {
  const room = await client.reconnect("wNHTX5qik", "SkNaHTazQ");
  console.log("joined successfully", room);

} catch (e) {
  console.error("join error", e);
}

reconnect 函数需要程序员手动调用, 或者建立某种任务机制实现自动调用. Colyseus 内部不会自动调用.

官方 Unity SDK 中的 Example 中也有更为严谨的处理断线重连的方法可供参考.

关于 websocket 长连接:
是的, nginx 有超时断开机制, 但是参考官方文档就会发现, 可以任意配置超时时间.

server {
    listen 80;
    listen 443 ssl;
    server\_name yourdomain.com;

    ssl_certificate /path/to/your/cert.crt;
    ssl_certificate_key /path/to/your/cert.key;

    location / {
        proxy_pass http://localhost:2567;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_read_timeout 86400s;
        proxy_send_timeout 86400s;
    }
}

这里配置了24小时不断连, 基本上可以满足所有需求了.
当然可以配合心跳, 心跳机制需要程序员自己实现, 简单的一个client.send()即可.