Python扭曲 - 需要通过所有连接并找到客户端

Ale*_*x R 1 python connection twisted

我正在尝试创建一个简单的凭证计划.

客户端连接到服务器并询问凭证是否还有剩余时间,如果是,服务器会响应多长时间.

我控制了服务器和客户端,客户端也由我编码.

现在这就是我的服务器端,客户端是自我解释的.

这方面的一个重大缺陷是,如果2个客户端连接相同的凭证代码,他们都将具有访问权限,因为服务器没有检查是否存在具有该代码的活动客户端.

任何人都可以解释或导致文件如何可能吗?

#!/usr/bin/env python

from twisted.internet import reactor, protocol

class Responder(protocol.Protocol):

    def dataReceived(self, data):
        # check the voucher code, and return disabled if its out of time or not there. Otherwise return time left.
        if data.startswith("check="):
            param, vcode = data.split("=")
            checkcode = SQLConnect("check", vcode, vcode)
            if checkcode == "disabled":
                self.transport.write("disabled")
            else:
                self.transport.write(str(checkcode))
        # Update time left.
        if data.startswith("update="):
            param, vcode, vtime = data.split("=")
            SQLConnect("update", vcode, vtime)

def main():
    factory = protocol.ServerFactory()
    factory.protocol = Responder
    reactor.listenTCP(6500,factory)
    reactor.run()

if __name__ == '__main__':
    main()
Run Code Online (Sandbox Code Playgroud)

Jea*_*one 5

如果凭证在客户端检查时变为"正在使用",然后在客户端断开连接时变为未使用,则听起来您需要保留一组您在检查完成时添加的凭证,并在客户端断开连接时删除.您可以将其保留在工厂中,以便在所有客户端连接之间共享.例如:

#!/usr/bin/env python

from twisted.internet import reactor, protocol

class Responder(protocol.Protocol):
    def connectionMade(self):
        self.vcode = None

    def dataReceived(self, data):
        # check the voucher code, and return disabled if its out of time or not there. Otherwise return time left.
        if data.startswith("check="):
            param, vcode = data.split("=")
            if vcode in self.factory.activeVouchers:
                self.transport.write("in use")
                return
            self.factory.activeVouchers.add(vcode)
            self.vcode = vcode

            checkcode = SQLConnect("check", vcode, vcode)
            if checkcode == "disabled":
                self.transport.write("disabled")
            else:
                self.transport.write(str(checkcode))
        # Update time left.
        if data.startswith("update="):
            param, vcode, vtime = data.split("=")
            SQLConnect("update", vcode, vtime)

    def connectionLost(self, reason):
        if self.vcode is not None:
            self.factory.activeVouchers.remove(self.vcode)

def main():
    factory = protocol.ServerFactory()
    factory.activeVouchers = set()
    factory.protocol = Responder
    reactor.listenTCP(6500,factory)
    reactor.run()

if __name__ == '__main__':
    main()
Run Code Online (Sandbox Code Playgroud)

vcode属性on Responder允许在activeVouchers客户端断开连接时触发集合(触发Responder.connectionLost调用).附近的附加检查会在使用时Responder.dataReceived将凭证添加到该集合中,并防止使用任何使用凭证.

除此之外,您还可以考虑其他一些事项.首先,您应该使用twisted.protocols.basic.LineOnlyReceiver或使用其他协议twisted.protocols.basic而不是仅使用其他协议Protocol. dataReceived只要通过网络接收到任何字节,就会调用它.由于TCP是面向流的传输而不是面向消息的传输,因此您最终可能会dataReceived("chec")快速跟注dataReceived("k=somecode").由于您dataReceived现在已经实施,因此不会处理此案例,客户端也不会收到任何响应. LineOnlyReceiver添加基于行的成帧,以便像"check = somecode\r \n"这样的字节可以被解释为完整的消息,并且在一次lineReceived调用中一次性地传递"check = somecode" .

其次,SQLConnect看起来它可能执行一些阻塞I/O. 如果这是真的,则意味着您的服务器将无法很好地处理并发客户端请求,因为任何阻止都会阻止处理所有新事件,包括来自不同客户端的事件.您可能希望查看twisted.enterprise.adbapi非阻塞SQL API.