笔记-twisted
笔记-twisted
1. 简介
Twisted is an event-driven networking engine written in Python and licensed under the open source MIT license. Twisted runs on Python 2 and an ever growing subset also works with Python 3.
1.1. 什么是异步
最初始的程序是阻塞型的,就是一句一句执行,如果没有执行完,需要等待/阻塞,无疑,这样的架构在大部分时候会浪费处理能力,是比较低效的。
进程,线程更多的体现为硬件的资源分割和调度;到了单线程内,因为CPU和其它组件/网络的速度差异,仍然会空置大量处理能力。
为了提高线程内的效率,有了协程,但是协程仍不够抽象和高效,对复杂事件来说,代码复杂性很高;
其实协程在本文所讨论的情况下最主要的作用说就是存在大批量类似任务时,优先处理不需要等待其它条件的任务;
更进一步,把事件调度,分发机制抽象一下,独立出来,就是常说的异步+回调,事件驱动了;
1.2. overview
关键概念理解:
Protocol:定义如何处理消息;
Factory:实际处理的组件,可以理解为是工厂化的Protocol;
reactor:循环体,不停循环,接收事件/信号,分发事件/信号至对应处理类;
Application:更上层的结构体,管理多个service/reactor,最顶层的结构
其它相关概念:
defereeds:异步功能的关键,立即返回一个Deferred对象,它是一个承诺,意思是它所包含的任务一定会有一个结果,在有结果时会调用相应处理函数,如果正常则调用callback,异常则调用errback;当然,callback和errback可以是chain。
endpoints:对server,client更精确的操纵;
transport:对连接的描述及操纵。
上述概念理解后,剩下的细节就可以分步填充到框架里了。
除此之外,还有对数据库的异步支持,enterprice.adbapi
------部件理解------
2. reactor
参考文档:https://twistedmatrix.com/documents/current/api/twisted.internet.reactor.html
reactor实际是一个抽象,具体使用哪一种reactor依赖于平台,当然,也可以手动显示指定。
reactor类型
IReactorCore IReactorTime IReactorProcess
IReactorTCP IReactorSSL IReactorUDP
IReactorMulticast IReactorUNIX IReactorUNIXDatagram
IReactorFDSet IReactorThreads IReactorPluggableResolver
每个reactor都有不同的操作和属性:
以最常用的ireactorcore为例(核心)
常用属性有:
- run()
- stop()
- callWhenRunning(callable, *args, **kw)
- running
其它比较重要的还有消息注册和维护,不过一般用不到这么深,了解一下就可以了。
3. protocol
Protocol描述了如何以异步的方式处理网络中的事件,下面是一些典型的操作:
|
Method |
Return a prefix matching the class name, to identify log messages related to this protocol instance. |
|
|
Method |
Called whenever data is received. |
|
|
Method |
Called when the connection is shut down. |
|
|
Method |
Make a connection to a transport and a server. |
|
|
Method |
Called when a connection is made. |
4. factory
定义一些操作和持久化数据,在体系中可以理解为protocol的实例化。
class FingerFactory(protocol.ServerFactory):
protocol = FingerProtocol
def getUser(self, user):
return b"No such user"
5.
deferred
5.1.
deferred
# deferred 演示案例1
#
from twisted.internet import defer
from twisted.internet import task
from twisted.internet import reactor
# 耗时操作的外壳函数,返回一个deferred对象
# 完成之后的处理函数,使用task模拟了一个耗时操作
def time_wasted_wrapper(job_id):
def on_done():
print('time-wasted
job' + str(job_id) + 'done!')
return job_id
print('begin
time-wasted jon' + str(job_id))
return task.deferLater(reactor,
3, on_done)
# 回调函数
def on_one_job_done(result):
print('result
plus 1!')
return result + 1
def all_jobs_done(result):
print(str(result))
print(reactor.__class__)
print('all jobs
are done!')
reactor.stop()
time.sleep(1)
print(reactor.running)
# 模拟添加任务
def install_jobs():
jobs_list = list()
for i in range(10):
job = time_wasted_wrapper(i)
job.addCallback(on_one_job_done)
jobs_list.append(job)
deferred_list =
defer.DeferredList(jobs_list)
deferred_list.addCallback(all_jobs_done)
def run_module():
install_jobs()
print('all jobs
have started!')
reactor.run()
print('www')
print(reactor.running)
if __name__ == '__main__':
run_module()
# reactor.run()
5.2.
defer.inlineCallbacks
下面的代码演示了defer.inlineCallbacks的用法
# defer
# @defer.inlineCallbacks
#
from twisted.internet.defer import inlineCallbacks,
Deferred, returnValue
from twisted.python.failure import Failure
from twisted.internet import reactor, defer
def loadRemoteData(callback):
import time
time.sleep(1)
callback(1)
def loadRemoteData2(callback):
import time
time.sleep(1)
callback(2)
@defer.inlineCallbacks
def getRemoteData():
d1 = defer.Deferred()
print('start
execute r1!')
reactor.callInThread(loadRemoteData,
d1.callback)
r1 = yield d1
print('r1 =',r1)
d2 = defer.Deferred()
print('start
execute r2!')
reactor.callInThread(loadRemoteData2,
d2.callback)
r2 = yield d2
print('r2 =', r2)
returnValue(r1 + r2)
def getResult(v):
print ("result=", v)
if __name__ == '__main__':
d = getRemoteData()
d.addCallback(getResult)
reactor.callLater(4,
reactor.stop);
reactor.run()
6.
twisted理解-代码版
下面是一个逐步添加功能的twisted代码示例,能方便的理解twisted各个组件的作用及关系。
'''
# 1 基础的事务循环
# 创建了一个循环,没有监听任何端口
from twisted.internet import reactor
reactor.run()
'''
'''
# 2 进一步,声明endpoint,绑定,实现监听1079端口
from twisted.internet import protocol, reactor, endpoints
class FingerProtocol(protocol.Protocol):
pass
class FingerFactory(protocol.ServerFactory):
protocol = FingerProtocol
fingerEndpoint = endpoints.serverFromString(reactor, "tcp:1079")
fingerEndpoint.listen(FingerFactory())
reactor.run()
'''
'''
# 3 protocol丰富一些了,会读取一个输入<user>,并返回信息,然后中断连接
# LineReceiver是一个基本的protocol,它有一些方法,具体可查看api
from twisted.internet import protocol, reactor, endpoints
from twisted.protocols import basic
class FingerProtocol(basic.LineReceiver):
def lineReceived(self, user):
self.transport.write(self.factory.getUser(user)+
b"\r\n")
self.transport.loseConnection()
class FingerFactory(protocol.ServerFactory):
protocol = FingerProtocol
def getUser(self, user):
return b"No such user"
fingerEndpoint = endpoints.serverFromString(reactor, "tcp:1079")
fingerEndpoint.listen(FingerFactory())
reactor.run()
'''
'''
# 4 factory丰富一些了,有了一些方法和属性
# Read username, output from non-empty factory, drop connections
from twisted.internet import protocol, reactor, endpoints
from twisted.protocols import basic
class FingerProtocol(basic.LineReceiver):
def lineReceived(self, user):
self.transport.write(self.factory.getUser(user) + b"\r\n")
self.transport.loseConnection()
class FingerFactory(protocol.ServerFactory):
protocol = FingerProtocol
def __init__(self, users):
self.users = users
def getUser(self, user):
return self.users.get(user,
b"No such user")
fingerEndpoint = endpoints.serverFromString(reactor, "tcp:1079")
fingerEndpoint.listen(FingerFactory({ b'moshez' : b'Happy and well'}))
reactor.run()
'''
'''
# 5 加入了deferreds,并为它声明了callback和errback
# Read username, output from non-empty factory, drop connections
# Use deferreds, to minimize synchronicity assumptions
from twisted.internet import protocol, reactor, defer, endpoints
from twisted.protocols import basic
class FingerProtocol(basic.LineReceiver):
def lineReceived(self, user):
d = self.factory.getUser(user)
def onError(err):
return 'Internal error in
server'
d.addErrback(onError)
def writeResponse(message):
self.transport.write(message
+ b'\r\n')
self.transport.loseConnection()
d.addCallback(writeResponse)
class FingerFactory(protocol.ServerFactory):
protocol = FingerProtocol
def __init__(self, users):
self.users = users
def getUser(self, user):
return
defer.succeed(self.users.get(user, b"No such user"))
fingerEndpoint = endpoints.serverFromString(reactor, "tcp:1079")
fingerEndpoint.listen(FingerFactory({b'moshez': b'Happy and well'}))
reactor.run()
'''
'''
# 6 application 使用
from twisted.application import service, strports
from twisted.internet import protocol, reactor, defer
from twisted.protocols import basic
class FingerProtocol(basic.LineReceiver):
def lineReceived(self, user):
d = self.factory.getUser(user)
def onError(err):
return 'Internal error in
server'
d.addErrback(onError)
def writeResponse(message):
self.transport.write(message
+ b'\r\n')
self.transport.loseConnection()
d.addCallback(writeResponse)
class FingerFactory(protocol.ServerFactory):
protocol = FingerProtocol
def __init__(self, users):
self.users = users
def getUser(self, user):
return
defer.succeed(self.users.get(user, b"No such user"))
application = service.Application('finger', uid=1, gid=1)
factory = FingerFactory({b'moshez': b'Happy and well'})
strports.service("tcp:79", factory,
reactor=reactor).setServiceParent(
service.IServiceCollection(application))
'''
7.
参考文档:
https://twistedmatrix.com/documents/current/core/howto/tutorial/intro.html
笔记-twisted的更多相关文章
- 笔记-twisted源码-import reactor解析
笔记-twisted源码-import reactor解析 1. twisted源码解析-1 twisted reactor实现原理: 第一步: from twisted.internet ...
- twisted学习笔记No.3 Web Clients
原创博文,转载请注明出处. 这一章我们学习利用twisted建立web 客户端. twisted.web.client.getPage用来异步下载一个页面,并且返回一个deferred from tw ...
- twisted学习笔记 No.1
原创博文,转载请注明出处 . 1.安装twisted ,然后安装PyOpenSSL(一个Python开源OpenSSL库),这个软件包用于给Twisted提供加密传输支持(SSL).最后,安装PyCr ...
- 笔记-scrapy与twisted
笔记-scrapy与twisted Scrapy使用了Twisted作为框架,Twisted有些特殊的地方是它是事件驱动的,并且比较适合异步的代码. 在任何情况下,都不要写阻塞的代码.阻塞的代码包括: ...
- twisted 学习笔记二:创建一个简单TCP客户端
#coding=utf-8 from twisted.internet import reactor,protocol class QuickClient(protocol.Protocol): de ...
- twisted学习笔记 No.2 WebServer
原创博文,转载请注明出处. 当服务器接收到一个客户端请求后,会创建一个请求对象并传递到资源系统,资源系统会根据请求路径分发到相应的资源对象,资源被要求渲染自身并返回结果到客户端. 解析HTTP Req ...
- twisted学习笔记4 部署Twisted 应用程序
原创博文,转载请注明出处. Twisted是一个可扩展,跨平台的网络服务器和客户端引擎. Twisted Application 框架有五个主要基础部分组成:服务,应用程序,TAC文件插件和twist ...
- twisted 学习笔记一:事件循环
from twisted.internet import reactor import time def printTime(): print "Current time is", ...
- 游戏服务器学习笔记 5———— twisted Perspective Broker 透明代理
实际上这章压根不需要我来说,twisted官网的Doc里面有专门介绍的章节.写的非常详细. http://twistedmatrix.com/documents/current/core/howto/ ...
随机推荐
- [SVN]TortoiseSVN工具培训1─为什么要用SVN?
你是否有经历过以下情况: SVN的使用理由/好处:
- 域名指向新的服务器IP后不能访问的解决办法
不能访问是因为本地DNS缓存,缓存清除方法:dos命令窗口输入ipconfig/flushdns ,回车即可.
- ASP.NET设置母版页
母版页允许开发人员创建具有指定的可编辑区域的站点级模板.随后,此模板可应用到网站中的 ASP.NET 页面上.这些 ASP.NET 页面只需为母版页中指定的可编辑区域提供相应内容 – 在使用母版页的所 ...
- 思科双出口+策略路由+NAT
使用策略路由,从教育网出去的,在教育网接口进行nat转换 访问教育网资源平时走教育网,故障走电信 访问internat走电信线路,故障走教育网 服务器静态绑定教育网ip,不管电信.联通.教育网都走教育 ...
- 笨办法学Python(二十五)
习题 25: 更多更多的练习 我们将做一些关于函数和变量的练习,以确认你真正掌握了这些知识.这节练习对你来说可以说是一本道:写程序,逐行研究,弄懂它. 不过这节练习还是有些不同,你不需要运行它,取而代 ...
- 51Nod 1600 Simple KMP SAM+LCT/树链剖分
1600 Simple KMP 对于一个字符串|S|,我们定义fail[i],表示最大的x使得S[1..x]=S[i-x+1..i],满足(x<i)显然对于一个字符串,如果我们将每个0<= ...
- 修改jupyter notebook的工作路径
两种方法 一 修改jupyter notebook快捷方式的属性 ①根据下图找到jupyter的快捷方式:jupyter notebook→更多→打开文件位置 ②右键打开属性-将目标一栏中最后的%US ...
- C盘压缩,电脑无法正常启动的解决方法?
有时候,我们觉得电脑很卡,因此压缩磁盘来节约资源,前段时间,由于不小心将C盘压缩了,导致电脑无法正常启动,查了一些有关的资料,发现很多人都遇到过类似的问题,如果你不想重装系统的话,那么,现在我说一下我 ...
- 计算最大矩形面积,POJ(2082)
题目链接:http://poj.org/problem?id=2082 把矩形按照高度一次递增的循序排列,当违反这一规则的时候,更新ans,用新的data替换之前的矩形.然后最后扫一遍. #inclu ...
- 【转】android布局--Android fill_parent、wrap_content和match_parent的区别
三个属性都用来适应视图的水平或垂直大小,一个以视图的内容或尺寸为基础的布局比精确地指定视图范围更加方便. 1)fill_parent 设置一个构件的布局为fill_parent将强制性地使构件扩展,以 ...