37,719
社区成员
发帖
与我相关
我的任务
分享
class MyClientProtocol(Protocol):
def connectionMade(self):
self.send_jsondata(None)
def send_jsondata(self, data):
json_data = {'head': 00006, 'client': 00001, 'cmd_id': 123}
send_data = json.dumps(json_data)
self.transport.write(send_data)
def dataReceived(self, data):
try:
recv_data = json.loads(data)
except:
print 'Failed loads data'
self.factory.process_data(recv_data)
def connectionLost(self, reason):
print reason
class MyClientFactory(ClientFactory):
protocol = MyClientProtocol
def __int__(self):
self.d = Deferred()
def process_data(self, recv_data=None):
d.callback(recv_data)
def process_event(recv_data):
if recv_data['head'] == 00012:
opener = Urllib2Opener()
username = recv_data['username']
password = recv_data['password']
login = Login(opener=opener, username=username, passwd=password)
print login.login()
def conn_server(host, port):
factory = MyClientFactory()
from twisted.internet import reactor
reactor.connectTCP(host, port, factory)
return factory.d
if __name__ == '__main__':
d = conn_server('127.0.0.1', 8007)
d.addCallback(process_event)
class MyClientProtocol(Protocol):
# ...
def dataReceived(self, data):
try:
recv_data = json.loads(data)
except:
print 'Failed loads data'
# 在这儿,process_data应该返回一个deferred object, 然后你可以加上一个callback来发送处理后的数据
d = self.factory.process_data()
d.addCallback(self.sendResult)
d.callback(recv_data)
class MyClientFactory(ClientFactory):
# ...
def process_data(self, recv_data=None):
# 不启动处理流程,只加上处理数据的callback,然后返回deferred object
d.addCallback(process_event)
return d
# d.callback(recv_data)
def process_event(recv_data):
if recv_data['head'] == 00012:
opener = Urllib2Opener()
username = recv_data['username']
password = recv_data['password']
login = Login(opener=opener, username=username, passwd=password)
print login.login()
# 返回处理完的数据
return "something"
这样,事件发生的流程是:
connect_server运行
--> TCP链接接收到数据
--> dataReceived函数运行
--> process_data返回d,d的callback列表为[process_event]
--> d.addCallback(self.sendResult)执行
--> d的callback列表成为[process_event, sendResult]
--> d.callback(recv_data)执行
--> 相当于sendResult(process_event(recv_data))
2. data可能是不完整的数据,这个在dataReceived的文档中明确提到了:
def dataReceived(self, data): (source)
Called whenever data is received.
Use this method to translate to a higher-level message. Usually, some callback will be made upon the receipt of each complete protocol message.
Parameters data a string of indeterminate length. Please keep in mind that you will probably need to buffer some data, as partial (or multiple) protocol messages may be received! I recommend that unit tests for protocols call through to this method with differing chunk sizes, down to one byte at a time.
3. 整个client实现一个protocol,负责收发数据。你的process_event是用来分发不同的数据给相应的处理函数的。
4. 找了几篇deferred的介绍,这个https://groups.google.com/forum/#!topic/python-tulip/ut4vTG-08k8对我用处最大。还有就是你的例子。
我的理解,deferred就是一台组装定制的机器,你先准备一个空壳,然后找人问:“您能不能给我装上搅拌机?”,“您能不能给我装上粉碎机?”“您能不能给我装上碾压机?”“您能不能给我装上挤压机?”,最后callback([面,水,肉]),得到饺子,但还是在机器的肚子里,取不出来。有人知道deferred的result能取出来吗?