我正在编写一个套接字服务器和 Flash 游戏客户端。游戏需要实时命令,例如移动和转弯。服务器尽快将这些命令发送到客户端非常重要,因为否则其他客户端将与移动/转动的客户端发生很多不同步。
这是由 Nagle 算法引起的问题的一个示例:
注意:如果您想了解这些命令的含义,请参阅下面的命令表。
第一个是我移动的船(前移+右移,前移已收到但右未收到)
客户端发送命令:
84796: Sending data: 2#4
84796: Sending data: 2#2
84904: Sending data: 2#3
84904: Sending data: 2#0
86187: Sending data: 2#4
86188: Sending data: 2#2
86374: Sending data: 2#3
86404: Sending data: 2#0
客户端接收命令:
79244: Raw receive: 3#3#4$
79244: New command: 3#3#4
79398: Raw receive: 3#3#2$3#3#3$3#3#0$
79399: New command: 3#3#2
79399: New command: 3#3#3
79399: New command: 3#3#0
80635: Raw receive: 3#3#4$
80635: New command: 3#3#4
80908: Raw receive: 3#3#2$3#3#3$3#3#0$
80908: New command: 3#3#2
80908: New command: 3#3#3
80908: New command: 3#3#0
“时刻”是一个奇怪的术语,并不意味着我想说什么,但这里似乎是上一个命令之后的毫秒数
客户端 A 向前发送(时刻:0),客户端 B 接收(时刻:0)
右转由客户端 A 发送(时刻:0),由客户端 B 接收(时刻:155)
停止移动客户端A发送(时刻:108),客户端B接收(时刻:0)
停止由客户端 A 发送(时刻:0),由客户端 B 接收(时刻:0)
客户端 A 向前发送(时刻:1283),客户端 B 接收(时刻:1236)
右转由客户端 A 发送(时刻:1),由客户端 B 接收(时刻:273)
停止移动由客户端 A 发送(时刻:186),由客户端 B 接收(时刻:0)
停止由客户端 A 发送(时刻:30),由客户端 B 接收(时刻:0)
这是与命令对应的命令表:
客户端-> 服务器
2# (movement info)
0) now not turning
1) now turning left
2) now turning right
3) now not moving
4) now moving forward
服务器-> 客户端
3# (movement info)
[shipId]#
0) now not turning
1) now turning left
2) now turning right
3) now not moving
4) now moving forward
因此,您可以看到,由于“Nagle”,这些命令完全不同步。这导致停止移动命令与开始移动命令同时被其他客户端接收,导致该玩家根本不移动。
这就是为什么我需要通过 TCP 服务器尽可能快地实时发送这些命令。一个简单的解决方法是简单地禁用 Nagle。但是,我已经搜索了一下(注意他关于 tcp message partial 的建议已在我的系统中实现,但与时间无关)并注意到人们绝对不建议禁用 Nagle。
我真的不应该因为这个原因禁用 Nagle 算法,而是应该寻找其他解决方案吗?为什么不)?
提前致谢。- 汤姆