笔记-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/ ...
随机推荐
- vue换一换功能原型
<html> <meta charset="utf-8"> <head> <script src="https://cdn.bo ...
- 将零散文件使用ICSharpCode.SharpZipLib压缩打包后一次性下载
public static Stream CreateZip(List<string> listPath, int level = 5) { MemoryStream mstream = ...
- 安卓手机下载YouTube视频的3种方法
作为全球最大的在线视频网站,YouTube上面的内容可真是应有尽有啊,从教学视频到个人手工艺品制作流程,从各种搞笑视频到电视连续集等等,包罗万象.如果你想下载YouTube视频到电脑上面的话,网上有很 ...
- *459. Repeated Substring Pattern (O(n^2)) two pointers could be better?
Given a non-empty string check if it can be constructed by taking a substring of it and appending mu ...
- CoreData的学习
第一步:创建项目是勾选coredata,当然创建的时候没有勾选,之后还可以手动生产, 然后:创建数据库模型,及为其添加模型的属性. 然后生成模型文件: 注意⚠️:首先设置为Manual/None 不 ...
- EBS R12中FND凭证打印警告:OPP响应超时
接近年关,最近年结忙的飞起,此为背景,今天运维那边反应日记账凭证打印报错,看了下后台请求发现请求有警告. 查看日志发现报了“并发:OPP响应超时”的警告,这个地方响应超时可能是配置文件中“并发:OPP ...
- 11_1_GUI
11_1_GUI 1. AWT AWT(Abstract Window Toolkit)包括了很多类和接口,用于Java Application的GUI(Graphics User Interface ...
- GCD中的线程死锁问题
GCD 确实好用 ,很强大,相比NSOpretion 无法提供 取消任务的功能. 如此强大的工具用不好可能会出现线程死锁. 如下代码: - (void)viewDidLoad { [super vie ...
- SQL基础语句汇总
连接数据库 1 mysql -h10.20.66.32 -uroot -p123456 -h后面是mysqlServer所在地址,-u后面是用户名,-p后面是密码 查看数据库 1 show datab ...
- 【模板时间】◆模板·III◆ 单调子序列
◆模板·III◆ 单调子序列 以前只知道DP用 O(n2) 的做法,现在才发现求单调子序列方法好多…… ◇ 模板简述 单调子序列包括 升序/降序/非升序/非降序 子序列.主要题型如下: ①在原串中找到 ...