0

我正在开发一个与 Twisted 套接字交互以允许在线游戏的二十一点 iPhone 应用程序。我目前的问题是找到正确的端口。让我解释。

我创建了一个名为“Table”的类。它保存像二十一点牌桌一样的信息,如位置、玩家和牌组。一张表分配给一个Twisted socket,一个socket分配给一个端口。现在,我只测试端口 1025-1034。

我想要发生的是应用程序请求按端口升序获取每张桌子上的玩家数量。为了测试,我只允许 1 个用户在一张桌子旁。如果有 1 个用户在一张桌子旁,我希望套接字返回 Table_Not_Found,但是,即使用户在一张桌子旁,套接字也会返回一个人所在的端口,而不是下一个没有人的端口。

我不认为我在使用 Table 类做正确的事情并搜索打开的表。如何找到正确的端口?应用程序连接到一个端口,如果该端口被占用,则返回 Table_Not_Found,然后应用程序请求下一个可用端口。但在我的情况下,套接字总是返回所占用的端口。我只能用我的 iMac 和 MacBook 进行测试,因为它们是客户端。

底线,我如何在端口上搜索可用的表?

谢谢!

class Table:
    def __init__(self):
        self.players = []
        self.positions = []
        self.id = 0
        self.numberOfPlayers = 0

    def setID(self, _id):
        self.id = _id

    def setActivePlayer(self, player):
        player.countdown = 20
        while player.count > 0:
            print player.countdown
            time.sleep(1)
            player.countdown -= 1

            if player.countdown == 0:
                print "Out of time"

                moves.surrender(player)


class Socket(Protocol):
    table = Table()

    def connectionMade(self):
        #self.transport.write("""connected""")
        self.factory.clients.append(self)
        print "Clients are ", self.factory.clients

    def connectionLost(self, reason):
        self.factory.clients.remove(self)

    def dataReceived(self, data):
        #print "data is ", data
        a = data.split(':')
        if len(a) > 1:
            command = a[0]
            content = a[1]

            b = content.split(';')
            _UDID = b[0].replace('\n', '')

            if command == "Number_of_Players":
                if Socket.table.numberOfPlayers == 0:
                    msg = "%s:TableFound" % _UDID
                elif Socket.table.numberOfPlayers == 1:
                    msg = "%s:Table_Not_Found" % _UDID

        print msg

        for c in self.factory.clients:
                c.message(msg)

    def message(self, message):
        self.transport.write(message)

NUM_TABLES = 10

factories = [ ]
for i in range(0, NUM_TABLES):
    print i
    factory = Factory()
    factory.protocol = Socket
    factory.clients = []
    factories.append(factory)
    reactor.listenTCP(1025+i, factory)
    #print "Blackjack server started"

reactor.run()
4

1 回答 1

2

您遇到的主要问题是table = Table()在您的套接字类中。这意味着对于所有Socket实例,只有一个Table.

快速解决方法是将每个存储Table在一个上,Factory以便所有到那个的连接Factory(即侦听 TCP 端口)将共享一个Table实例。

这可以通过删除table = Table()行来完成,然后for像这样修改循环:

for i in range(0, NUM_TABLES):
    print i
    factory = Factory()
    factory.table = Table() # <-- add this line
    factory.protocol = Socket
    factory.clients = []
    factories.append(factory)
    reactor.listenTCP(1025+i, factory)

然后调整你connectionMade的开始是这样的:

def connectionMade(self):
    self.table = self.factory.table

现在每个Socket都指向它FactoryTable.

但是,此代码还有许多其他严重问题:

  • 您不需要也不应该为此协议使用多个端口。每个新连接都应该显示出来,并通过协议本身的消息识别它想要玩的二十一点游戏。在多个端口上工作只会让人们更难通过防火墙来玩你的游戏。您可以使用相同的策略,只需在适当的实例上设置table属性。Socket

  • 您期望dataReceived收到完整的消息。 不会的,这是您应该在 Twisted 文档中阅读的常见问题解答。 或者更确切地说,它将是在您进行测试时,而不是在您部署到真正的互联网时。如果你在做 iPhone 开发,你应该使用 Network Link Conditioner 来模拟真实的互联网连接。

  • 由于您似乎不知道网络协议解析是如何工作的,因此您应该使用协议构建工具包AMP来构建您的有线协议。 API 文档包括一个简短的教程。

  • 你在打电话time.sleep。这将阻止整个服务器。这是构建时间敏感的 Twisted 服务的错​​误方法。更重要的是,Twisted 在等待您time.sleep完成时不会处理输入,因此每个玩家总是会立即投降,而不是能够打出任何牌。您应该callLater改用,来安排改变游戏状态的定时调用。

您遇到的大多数问题都是对象组合问题,而不是 Twisted 或 Python 所特有的问题。您需要为自己绘制一张地图,说明哪些实例应该指向哪些其他事物。要理解的重要一点是,当您像listenTCPor一样对反应器进行调用时callLater,您正在设置的是从反应器到您的对象的引用。它没有什么神奇之处。你只是说“稍后,在这种情况下,在这个对象上调用这个方法”。一切都从那里流出;你的套接字引用了你的桌子,你的桌子引用了他们的玩家,等等。

于 2012-06-03T20:58:13.037 回答