笔记-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/ ...
随机推荐
- int **a 和 int (*a)[]的区别
关于理论知识隔壁们的教程说的很详细了我就不多赘述了.我这边主要贴一段代码来看看这两种东西使用上的区别到底在哪. #include <stdio.h> int main(int argc, ...
- ARM实验4—按键轮询实验
key_poll按键轮询实验 实验内容: 通过FS_4412开发板上的按键控制LED灯并打印信息. 实验目的: 熟悉开发环境的使用. 掌握猎户座4412处理器的GPIO接口, 实验平台: FS4412 ...
- c++中explicit关键字用法
C++ explicit关键字用来修饰类的构造函数,表明该构造函数是显式的,既然有"显式"那么必然就有"隐式",那么什么是显示而什么又是隐式的呢? 如果c++类 ...
- java调用dll库
1.dll叫动态链接库,作用是用某种语言封装好某些函数生成可供不同语言调用的.dll文件,通常是用C++编写生成,因为C++可以对很多硬件操作方便而其他高级语言不行 2.dll生成参考:http:// ...
- NOIP2018学军中学游记(11.09~11.11)
前言 这篇博客记录的是我在\(NOIP2018\)提高组比赛中的经历. 这一次的\(NOIP\)是在学军中学举办的, 莫名感到一阵慌张. 但愿能有一个好成绩,不然就要\(AFO\)了... ... 说 ...
- 数黑格有多少个,模拟题,POJ(1656)
题目链接:http://poj.org/problem?id=1656 #include <stdio.h> #include <iostream> #include < ...
- Hubtown(最大流)
Hubtown 时间限制: 1 Sec 内存限制: 128 MB提交: 23 解决: 11[提交] [状态] [讨论版] [命题人:admin] 题目描述 Hubtown is a large N ...
- layui table 用法
1.使用模板列 改变样式 获取嵌套数据{ field: '', width: '12%', title: '响应状态', sort: true, templet: function (d) { if ...
- computed--实时计算属性
项目:https://github.com/ccyinghua/vue-node-mongodb-project/blob/master/07-shoppingCart.md 实时计算属性的compu ...
- Python 初始—(项目 目录结构)
在os 包下,给出 import os ,os.path.abspath(__file__)获取当前文件的相对路径,os.path.dirname 获取当前文件所在的文件夹目录 print(os.pa ...