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