【求助】关于Python的Twisted框架的使用。

菜鸟一只_热爱ASM 2013-10-26 04:44:05
小弟最近在看twisted的学习资料,对于deferred的编程一直不是很理解。希望大大指点一下,万分感谢。
1.比如下面这段代码,我连接上服务端然后请求一个任务,接收到数据后运用deferred根据head来判断做哪一个任务,但做完任务,有产生一些数据,我不知道怎么主动传到服务器,难道要在protocol里面实现吗?
2.protocol.dataReceived()接收到的数据是一次完整的self.transport.write()的数据吗?还是要等conncetionLost回调函数被调用才算整个完整的数据包?
3.是不是每个单独的事务都各自实现一个protocol和factory类,然后用Deferred的回调函数里面再调用connectionTCP来执行另外一个事务。还是整个client和server就各自实现一个protocol和factory类?
4.平常这个Deferred怎么使用或者代码中的哪个位置使用,有没有什么好的资料或者代码可以给我学习一下。谢谢了。

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)
...全文
259 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
jeky_zhang2013 2013-10-27
  • 打赏
  • 举报
回复
也想知道,帮顶下~~
panghuhu250 2013-10-27
  • 打赏
  • 举报
回复
(没有半点实践经验的回答) 1. 我觉得最合适的地方是在data_received函数中。下面代码中改了三处地方

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能取出来吗?
  • 打赏
  • 举报
回复
引用 2 楼 bugs2k 的回复:
http://wwty.iteye.com/blog/400987 http://blog.csdn.net/moxien/article/details/5344554
谢谢。你这两个我都看过了,没有回答我的问题啊。

37,719

社区成员

发帖
与我相关
我的任务
社区描述
JavaScript,VBScript,AngleScript,ActionScript,Shell,Perl,Ruby,Lua,Tcl,Scala,MaxScript 等脚本语言交流。
社区管理员
  • 脚本语言(Perl/Python)社区
  • IT.BOB
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧