【问题标题】:Can Socket.io emits arrive out of order? What if volatile?Socket.io 发射是否可以乱序到达?如果易变怎么办?
【发布时间】:2016-10-12 18:02:30
【问题描述】:

我一直在寻找一个明确的答案,但我似乎一直在寻找相互矛盾的答案(例如 thisthis)。

基本上,如果我

socket.emit('game_update', {n: 1});

从 node.js 服务器,然后,20 毫秒后,

socket.emit('game_update', {n: 2});

来自同一个服务器,有什么方法可以让 n:2 消息在 n:1 消息之前到达?换句话说,如果 n:1 消息在途中丢失,n:1 消息是否会“阻止”接收 n:2 消息?

如果它们是 volatile 发射怎么办?我的理解是 n:1 消息不会阻塞 n:2 消息——如果 n:1 消息被丢弃,n:2 消息在到达时仍会收到。

背景:我正在构建一个 node.js 游戏服务器,并希望更好地了解我的游戏更新是如何传播的。我现在正在使用 volatile emit,我想提高服务器的滴答率,但我想确保独立的游戏更新不会相互阻塞。我宁愿客户端每 30 毫秒接收一次更新,其中散布一些丢弃的更新,而不是让客户端接收更新,在 200 毫秒内什么也没收到,然后一次接收 6 个以上的更新。

【问题讨论】:

    标签: javascript node.js websocket socket.io


    【解决方案1】:

    免责声明:我对socket.io 的内部结构并不完全熟悉。

    有什么方法可以让 n:2 消息在 n:1 消息之前到达?

    这取决于您使用的传输方式。对于polling 传输,我认为可以公平地说,消息完全有可能无序到达,因为每条消息都可以通过不同的连接到达。

    使用websocket 传输,保持持久连接,合理保证消息顺序。

    如果它们是 volatile 发射怎么办?

    有了 volatile 发射,所有的赌注都被取消了,它是一劳永逸的。我认为在正常情况下,服务器会等待(并将消息排队)等待客户端准备好接收消息,除非这些消息是易变的,在这种情况下,服务器会丢弃它们。

    根据您的说法,我认为 volatile 发出是您想要的,尽管一旦建立了 websocket 连接,我认为您不会看到所描述的场景(“接收更新,接收200 毫秒内什么都没有,然后一次又收到 6 次更新”)可能会发生。也许只有当连接丢失并重新建立时。

    【讨论】:

      【解决方案2】:

      答案是肯定的,它可能会在以后到达,但考虑到套接字本质上是持久连接并且顺序的可靠性几乎得到保证,这是极不可能的。

      根据 Socket.io 文档,在客户端未连接的情况下,消息将被丢弃。这不一定适合您的用例,但是在文档本身中,如果您需要发送角色的位置,它将 Volatile 事件描述为一个有趣的示例。

      // server-side
      io.on("connection", (socket) => {
        console.log("connect");
      
        socket.on("ping", (count) => {
          console.log(count);
        });
      });
      
      // client-side
      let count = 0;
      setInterval(() => {
        socket.volatile.emit("ping", ++count);
      }, 1000);
      

      如果你重启服务器,你会在控制台看到:

      connect
      1
      2
      3
      4
      # the server is restarted, the client automatically reconnects
      connect
      9
      10
      11
      

      没有 volatile 标志,您会看到:

      connect
      1
      2
      3
      4
      # the server is restarted, the client automatically reconnects and sends its 
      buffered events
      connect
      5
      6
      7
      8
      9
      10
      11
      

      注意:文档明确指出这将在服务器重新启动期间发生,这意味着您可能必须断开与客户端的连接才能删除 volatile 发射。

      我想说一个好的做法是将你的发射写成 volatile 以防万一你得到一个丢弃的客户端,但这在很大程度上取决于你的游戏要求。

      至于目标,我建议您使用某种动态时间系统或基于客户端和服务器保持同步时钟的增量时间来使用客户端预测,以帮助缓解您可能遇到的一些问题。下面是一个示例,说明如何做到这一点,虽然我不喜欢创建者的语法,但它可以很容易地适应您的需求。

      希望这对遇到这个话题的人有所帮助。

      Socket.io - Volatile events

      Client Side Prediction

      【讨论】:

        猜你喜欢
        • 2019-02-10
        • 1970-01-01
        • 2021-06-26
        • 1970-01-01
        • 2020-03-25
        • 1970-01-01
        • 1970-01-01
        • 2018-03-04
        • 1970-01-01
        相关资源
        最近更新 更多