【发布时间】:2013-01-13 07:57:56
【问题描述】:
我正在尝试使用 Twisted 和 Pygame 开发简单的TCP 客户端/服务器游戏,但我在向客户端发送数据时遇到了困难。 Twisted 不允许我连续发送多个回复。这就是我想要做的:
我有方法可以处理播放器状态更改并将它们重新发送给其他客户端:
def handle_stateChanged(self, data):
#get playerState from client and override local copy of player
#check if all players are ready
#if needed, change gameState form 'inLOBBY' to 'inGAME'
#if gameState == 'inGAME', start 'proceed' method (see below)
#send message about player and game state to others
和proceed 方法(使用LoopingCall 每1s/30 调用一次)只需计算所有游戏内容并将其发送给玩家。这两个函数相互阻塞,单独工作得很好,但是当它们一起工作时,只有其中一个函数的数据到达目的地。像这样的东西也不起作用:
def dataRecived(self, data):
...
sendData(data1) #only data1 is delivered
sendData(data2)
...
我不知道这是 TCP 的工作方式还是我对 Twisted 缺乏了解。 我应该如何向客户端发送更新并在后台处理用户输入?
编辑:
class Server(Protocol):
def __init__(self, factory):
self.factory = factory
self.player = None #when connection is made here goes my player class
self.world = factory.world
...
self.factory.loop = LoopingCall(self.proceed)
def dataReceived(self, data):
data = pickle.loads(data)
#this calls 'handle_stateChanged'
getattr(self, 'handle_{}'.format(data['header']))(data) #data[header] = 'stateChanged'
def handle_stateChanged(self, data):
isReady = data['isReady']
self.player.isReady = isReady
if isReady:
count = 0
for connection in self.factory.connections.values():
if connection.player.isReady:
count += 1
if count == len(self.factory.connections) and count > 1 and self.world.state == 'inLOBBY':
self.world.state = 'inGAME'
self.world.playersDistribution(self.factory.connections)
self.factory.loop.start(1 / 30)
data['state'] = self.world.state
data['players'] = self.getPlayers()
self.sendToOthers(data)
def sendToOthers(self, data, omitId = None):
connections = self.factory.connections
for key in connections.keys():
if key != omitId:
connections[key].sendData(data)
def proceed(self):
#It's only a prototype of my method.
#The point is that the client keep getting
#'test' and data from self.sendToOthers(data) in handle_stateChanged
#is not being delivered even if the method (handle_stateChanged) is called
if self.world.state != 'inGAME':
return
data = {'header' : 'message', 'body' : 'test'}
#When i comment this out, handle_stateChanged works fine and sends data
self.sendToOthers(data)
class ServerFactory(Factory):
def __init__(self, world):
self.world = world
self.connections = {}
def buildProtocol(self, addr):
return Server(self)
【问题讨论】:
-
你不能在后台做任何事情,因为 Twisted 是基于事件的(除非你开始自己的线程,但不建议这样做)。你能展示更多你的代码吗?
-
我的意思是
proceed被LoopingCall调用,handle_stateChanged在每次客户端发送消息时被调用:'player is ready',所以背景是一个错误的词。我添加了一些代码。
标签: python networking twisted