实时对战 Play bug

首先,cocos creator 导入插件不好用,只能不导入插件,用require方式才能访问
另外,
client.reconnectAndRejoin(); 这个方法,有点疑问
在reconnectAndRejoin(比如房间号不存在了)失败后,再次操作会报一个 ws.readyState 为null的错误。最后我只能用先reconnect再rejoin的形式。
实际上,我觉得reconnectAndRejoin就算失败了,但connect不一定失败。

现在又发现如果能用先reconnect再rejoin的形式。ios自己断网再连接测试,rejoin会报房间已满错误

还有一个

如果房主掉线了,服务器换了master了,但客户端没有收到MASTER_SWITCHED回调
房主主动离开的情况,MASTER_SWITCHED回调正常

  1. 针对引擎工具的导入方式,我们在新版 SDK 中对 Cocos, Laya, Egret 做了统一导入,由引擎负责加载插件后,开发者直接引用,请参考
  2. reconnectAndRejoin() 的问题我会确认一下。
  3. 房主掉线的情况,是指真的离开房间了,还是离线了?(区别在于是否在玩家的 ttl 时间内),稍后我也会确认一下。

非常感谢你的反馈!

谢谢你的回复。

关于第三个问题,房主掉线了,然后重连成功了。这个时候,服务的其实已经更换了房主了。
但是其他客户端,自始至终没有收到 MASTER_SWITCHED 的回调,
有新客户端加进来,就可以看到实际上房主已经换了。但之前房间里的客户端,并没有收到房主已经更换了的回调。调用master.userId等接口,还是之前未更改的房主号。

再次感谢你的反馈!
今天我们会把你遇到的问题排查并解决掉。
欢迎加入到我们的游戏开发 QQ 群 202832656,希望可以更及时的沟通交流!

针对这个问题,我尝试复现了一下场景,不知道和你描述的是否有出入:
p0 创建房间(默认是房主),p1, p2 加入房间;p0 离开房间,此时 p1,p2 会收到房主切换的事件(MASTER_SWITCHED),结果和预期一致
具体测试代码为:

it('test master leave', () =>
    new Promise(async resolve => {
      const roomName = 'tm1_r';
      const p0 = newPlay('tm1_0');
      const p1 = newPlay('tm1_1');
      const p2 = newPlay('tm1_2');
      let f1 = false;
      let f2 = false;

      await p0.connect();
  await p0.createRoom({ roomName });
  await p1.connect();
  await p1.joinRoom(roomName);
  p1.on(Event.MASTER_SWITCHED, async data => {
    const { newMaster } = data;
    debug(`new master: ${newMaster.actorId}`);
    f1 = true;
    if (f1 && f2) {
      await p0.disconnect();
      await p1.disconnect();
      await p2.disconnect();
      resolve();
    }
  });
  await p2.connect();
  await p2.joinRoom(roomName);
  p2.on(Event.MASTER_SWITCHED, async data => {
    const { newMaster } = data;
    debug(`new mater: ${newMaster.actorId}`);
    f2 = true;
    if (f1 && f2) {
      await p0.disconnect();
      await p1.disconnect();
      await p2.disconnect();
      resolve();
    }
  });
  await p0.leaveRoom();
}));

针对这个问题,我做了如下测试,p0 创建 playerTtl = 600 的房间,p1 加入房间;p1 断线后,重连(reconnect())并返回之前的房间(rejoin()),结果符合预期,测试代码如下:

it('test reconnect and rejoin', async () => {
    const roomName = 'tm2_r';
    const p0 = newPlay('tm2_0');
    const p1 = newPlay('tm2_1');

    await p0.connect();
    const roomOptions = {
      playerTtl: 600,
    };
    await p0.createRoom({ roomName, roomOptions });
    await p1.connect();
    await p1.joinRoom(roomName);
    await p1.disconnect();
    await p1.reconnect();
    await p1.rejoinRoom(roomName);

    await p0.disconnect();
    await p1.disconnect();
  });

这里有个需要注意的地方:如果需要「返回房间」(rejoin()),则需要设置 playerTtl,这个字段的含义是玩家掉线后,在房间保留数据的时长(单位:秒)

针对这个问题,我做了如下测试:p0 创建 playerTtl=5 的房间,p1 加入后断线,p0 也离开房间(为了使房间销毁);等待 10s 后,p1 重连并返回房间(reconnectAndRejoinRoom()),此时会报加入房间错误(房间不存在),然后可以再创建其他房间,结果符合预期。具体代码如下:

function wait(delay) {
    return new Promise(resolve => {
      setTimeout(() => {
        resolve();
      }, delay);
    });
  }

it('test reconnectAndRejoin', async () => {
    const roomName = 'tm3_r';
    const p0 = newPlay('tm3_0');
    const p1 = newPlay('tm3_1');

    await p0.connect();
    const roomOptions = {
      playerTtl: 5,
    };
    await p0.createRoom({ roomName, roomOptions });
    await p1.connect();
    await p1.joinRoom(roomName);
    await p1.disconnect();
    await p0.leaveRoom();

    await wait(10000);
    try {
      await p1.reconnectAndRejoin();
    } catch (err) {
      if (err.code === 4301) {
        debug('rejoin failed');
        await p1.createRoom();
        await p0.disconnect();
        await p1.disconnect();
      }
    }
  });

你提到的 connect 失败,是否是因为网络连接没有建立起来呢?reconnectAndRejoinRoom() = reconnect() + rejoinRoom()

我问题描述,所指的是p0房主掉线,而不是p0房主主动离开房间。
p0掉线后,服务器房主已经切换,但房间内的其他客户端未收到但是其他客户端,没有收到 MASTER_SWITCHED 的回调。
p0掉线重连成功后,p0因为有重连操作,p0内部信息有更新,可以知道房主已经切换

保持时间我知道,但我遇到的,没有涉及到这个,实际上就是在这个时间内
我是ios原生平台测试发现的。而是我主动把p1(在ios端)的网络关掉。再马上重连,会报房间已满
所有操作都在playerTtl时间内。就是不在这个时间内,反而房间应该已经只有3个人了,应该也可以加入

关于这个问题,我后来还是用reconnectAndRejoin方法了

请加入到 QQ 群:202832656,这是我们专门的游戏开发服务群,方便解决你的问题。

如果是网络连接没有建立起来,“此时会报加入房间错误(房间不存在)” 不会走到这一步,会直接报socket错误。连接都没成功,怎么还会知道房间还存在不存在
只有连接成功了,才会报 “此时会报加入房间错误(房间不存在)”

我是确实多次捕捉到了ws.readyState 为null的错误,就是在你操作 再创建其他房间 的时候报的错。
我倒是忘记了,在网页上测试时,有没有遇到过这个问题

我做测试时,因为要做断线重连。所以会有两种方法测试,一种是后台挂起测试,一种是直接断网重连测试

另外,我是ios原生平台 和网页,共同测试。一些问题,可能网页上不会碰到,到ios原生平台就碰到了

这个「房间已满」是在什么状态下发生的?
比如说房间最大人数是几人,是通过 join() 还是 rejoin() 报的房间已满?
我描述一种场景:p0 创建房间,且设置最大人数为 2 人,playerTtl=600,p1 加入房间;此时 p1 掉线,再连接成功后:
如果 p1.joinRoom(),则会报「房间已满」,因为这个房间还有 p1 的离线数据。
如果 p1.rejoinRoom(),则正常,相当于 p1 「返回」房间。
不知道你说的是不是这种情况?

这样吧,我之后测试在碰到的时候,马上截图,在看看

好的,非常感谢!

我们这边也会再多做一些测试,希望你能加入到 qq 群,这样有问题反馈解决都会更及时!