我正在开发一款实时MMO游戏,并且有一个有效的TCP服务器(以及游戏客户端),但现在我考虑使用UDP 来不断更新其他玩家的位置(大大提高)从TCP拥塞控制中减少随机游戏填充!) 我喜欢这些东西比我更聪明的人的帮助(我是python / twisted的新手,在其他地方找不到这些信息;)
目前,我的服务器接受使用简单Twisted协议的连接。例如
global $brand_name = $row['brand_name'];
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 如何单独为每个协议实例实施拥塞检查?请在下面的代码示例中启动我的内容:(在这里说“请帮助!”) 我错误地想到了这个吗?任何指导都很棒,谢谢!
''' TCP reciever '''
class TCPProtocol(Protocol):
def connectionMade(self):
#add to list of connected clients
factory.clients.append(self)
def dataReceived(self, data):
pass
#setup factory and TCP protocol class
factory = Factory()
factory.protocol = TCPProtocol
factory.clients = []
reactor.listenTCP(1959, factory)
答案 0 :(得分:9)
You probably don't need UDP (yet)
你要说的第一件事是你想要减少来自TCP"的网络拥塞......这不是UDP的作用。 UDP允许您解决拥塞控制,实际上增加网络拥塞。在您了解如何实施自己的拥塞控制算法之前,高延迟连接上的UDP流量只会导致数据包风暴,从而使您的服务器不堪重负并淹没您的用户。网络连接,使它们无法使用。
在实时游戏中发送移动数据包的重要一点是,你总是希望确保不浪费时间和追赶"当新位置已经可用时,使用旧的移动包。在Twisted中,您可以使用producer and consumer APIs在TCP连接上执行此操作,就像这样:
from zope.interface import implementer
from twisted.internet.protocol import Protocol
from twisted.internet.interfaces import IPullProducer
def serializePosition(position):
"... take a 'position', return some bytes ..."
@implementer(IPullProducer)
class MovementUpdater(Protocol, object):
def updatePosition(self, newPosition):
if newPosition != self.currentPosition:
self.currentPosition = newPosition
self.needToSendPosition()
waitingToSend = False
def needToSendPosition(self):
if not self.waitingToSend:
self.waitingToSend = True
self.transport.registerProducer(self, False)
def resumeProducing(self):
self.transport.write(serializePosition(self.currentPosition))
self.transport.unregisterProducer()
self.waitingToSend = False
def stopProducing(self):
"nothing to do here"
每次游戏需要发送新位置时,都可以调用updatePosition
来更新玩家的当前位置。 updatePosition
首先更新当前位置,然后调用needToSendPosition
,标记连接需要发送位置更新。这将协议注册为其传输的生成器,这将在每次写入缓冲区空间可用时调用resumeProducing
。一旦resumeProducing
被调用,我们就会发送最新位置的任何内容 - 如果在网络拥塞时调用updatePosition
500次,则只会立即发送一次更新随着拥堵的缓解。
这有点过于简单,因为每个transport
一次只能有一个producer
,而您的游戏服务器可能会有很多不同的位置更新发送给客户,因此您需要一个多路复用器,它聚合来自多个客户端的所有位置更新,还有一些代码来订购消息,这样除了位置更新之外的其他东西仍然可以通过,但位置更新具有优先权。
如果您仍然要进行UDP,这似乎是额外的工作,但如果您要正确地执行UDP并从中获得任何好处,您将需要实现非常类似的东西无论如何,所以这不会浪费。