求熟悉Twisted底层的大神帮助。我的TCP端口服务器一直服务正常,可是一旦加入Redis之后,却不再返回数据了?classPlainTCP(protocol.Protocol):def__init__(self,factory):passdefconnectionMade(self):self.factory.numConnections+=1print"Nr.ofconnections:%d\n"%(self.factory.numConnections)self.transport.write("Helloremote\r\n")defconnectionLost(self,reason):self.factory.numConnections-=1print"Nr.ofconnections:%d\n"%(self.factory.numConnections)defdataReceived(self,data):(self.snrCode,rDat,pDat)=getDataParsed(data)self.transport.write(data)以上代码在远程客户端可以立即获得复制的数据而增加了SQL/Redis数据保存后,事情变得奇怪了。#!/usr/bin/envpythonimporttimeimportbinasciiimporttxredisapifromtwisted.internetimportdeferfromtwisted.internetimportprotocol,reactorfromtwisted.internet.protocolimportFactoryfromtwisted.enterpriseimportadbapifromtwisted.pythonimportlogfromdmpackimportDmpackfromdmdbimportDmdbfromdmconfigimportDmConfdm=Dmpack()conf=DmConf().loadConf()rcs=txredisapi.lazyConnection(password=conf['RedisPassword'])dbpool=adbapi.ConnectionPool("MySQLdb",db=conf['DbName'],user=conf['DbAccount'],\passwd=conf['DbPassword'],host=conf['DbHost'],\use_unicode=True,charset=conf['DbCharset'])defgetDataParsed(data):realtime=Noneperiod=NonesnrCode=dm.snrToAscii(data[2:7])realtime=data[7:167]perid=data[167:-2]return(snrCode,realtime,period)classPlainTCP(protocol.Protocol):def__init__(self,factory):self.factory=factoryself.factory.numConnections=0self.snrCode=Noneself.rData=Noneself.pData=Noneself.err=NonedefconnectionMade(self):self.factory.numConnections+=1print"Nr.ofconnections:%d\n"%(self.factory.numConnections)self.transport.write("Helloremote\r\n")##这里也不返回数据了defconnectionLost(self,reason):self.factory.numConnections-=1print"Nr.ofconnections:%d\n"%(self.factory.numConnections)@defer.inlineCallbacksdefdataReceived(self,data):globaldbpool,rcs(self.snrCode,rDat,pDat)=getDataParsed(data)ifself.snrCode==NoneorrDat==NoneorpDat==None:err="Badformat"else:err="OK"print"err:%s"%(err)###这里可以在终端打印数据self.err=errself.transport.write(self.snrCode)###没有数据返回self.transport.write(self.err)self.transport.write(rDat)self.transport.write(pDat)self.transport.loseConnection()ifself.snrCode!=NoneandrDat!=NoneandpDat!=None:res=yieldself.saveRealTimeData(rcs,rDat)res=yieldself.savePeriodData(dbpool,pDat,conf)print"err2:%s"%(err)###终端有打印@defer.inlineCallbacksdefsaveRealTimeData(self,rc,dat):yieldrc.set(key,val)###自己脑补Key、Valyieldrc.expire(key,30)###可以保存,已经确认@defer.inlineCallbacksdefsavePeriodData(self,rc,dat,conf):query="insert....."###自己脑补SQLyieldrc.runQuery(query)###可以保存,已经确认classPlainTCPFactory(protocol.Factory):defbuildProtocol(self,addr):returnPlainTCP(self)defmain():dmdb=Dmdb()ifnotdmdb.detectDb():print"PleaserunMySQLRDBSfirst."sys.exit()log.startLogging(sys.stdout)reactor.listenTCP(8080,PlainTCPFactory())reactor.run()if__name__=="__main__":main()现象是一旦加入了异步库之后,socket就不在回传了。原始Demo中self.transport.write()没有任何修饰符,所以这应该是同步的。搞不懂异步数据库加入后,为何连connectionMade()这个不相关的句柄中的write()也被失效了。而同时print却是有效的?
2 回答
慕姐4208626
TA贡献1852条经验 获得超7个赞
谢谢大哥关注这个问题。这个是2015年的问题,所以我花了一番力气才看懂我自己的问题,慢慢回想起来。因为当时我根本没有找到答案,所以只有一步步地反复调整。最后结论是调用异步方式本身不需要yield。因为一旦调用者yield,就调用者也成了生成器了。所以内嵌print也就不执行了。@defer.inlineCallbacks#这里不需要@defer.inlineCallbacksdefdataReceived(self,data):res=yieldself.saveRealTimeData(rcs,rDat)#这里不需要yield@defer.inlineCallbacksdefsaveRealTimeData(self,rc,dat,conf):yieldrc.set(key,val)#这里需要保留yieldyieldrc.expire(key,conf['RedisDataTTL'])宗旨:@defer.inlineCallback修饰的函数里必然有yield;异步函数方法调用者不要再使用异步。
添加回答
举报
0/150
提交
取消
