博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
5.Twisted学习
阅读量:5323 次
发布时间:2019-06-14

本文共 12526 字,大约阅读时间需要 41 分钟。

1 from twisted.application import service, strports 2 from twisted.internet import protocol, reactor, defer 3 from twisted.protocols import basic 4  5 class FingerProtocol(basic.LineReceiver): 6     def lineReceived(self, user): 7         d = self.factory.getUser(user) 8  9         def onError(err):10             return b'Internal error in server'11         d.addErrback(onError)12 13         def writeResponse(message):14             self.transport.write(message + b'\r\n')15             self.transport.loseConnection()16         d.addCallback(writeResponse)17 18 class FingerFactory(protocol.ServerFactory):19     protocol = FingerProtocol20 21     def __init__(self, users):22         self.users = users23 24     def getUser(self, user):25         return defer.succeed(self.users.get(user, b"No such user"))26 27 class FingerSetterProtocol(basic.LineReceiver):28     def connectionMade(self):29         self.lines = []30 31     def lineReceived(self, line):32         self.lines.append(line)33 34     def connectionLost(self, reason):35         user = self.lines[0]36         status = self.lines[1]37         self.factory.setUser(user, status)38 39 class FingerSetterFactory(protocol.ServerFactory):40     protocol = FingerSetterProtocol41 42     def __init__(self, fingerFactory):43         self.fingerFactory = fingerFactory44 45     def setUser(self, user, status):46         self.fingerFactory.users[user] = status47 48 ff = FingerFactory({b'moshez': b'Happy and well'})49 fsf = FingerSetterFactory(ff)50 51 application = service.Application('finger', uid=1, gid=1)52 serviceCollection = service.IServiceCollection(application)53 strports.service("tcp:79", ff).setServiceParent(serviceCollection)54 strports.service("tcp:1079", fsf).setServiceParent(serviceCollection)

这个项目有两个协议-工厂类,每一个都是application的子程序。更具体地说,setServiceParents方法把两个服务定义为application,实现了IServiceCollections。这两个服务都由应用程序启动。

使用Services让依赖更加合理

使用服务基类,实现泛型行为

1 from twisted.application import service, strports 2 from twisted.internet import protocol, reactor, defer 3 from twisted.protocols import basic 4  5 class FingerProtocol(basic.LineReceiver): 6     def lineReceived(self, user): 7         d = self.factory.getUser(user) 8  9         def onError(err):10             return b'Internal error in server'11         d.addErrback(onError)12 13         def writeResponse(message):14             self.transport.write(message + b'\r\n')15             self.transport.loseConnection()16         d.addCallback(writeResponse)17 18 class FingerSetterProtocol(basic.LineReceiver):19     def connectionMade(self):20         self.lines = []21 22     def lineReceived(self, line):23         self.lines.append(line)24 25     def connectionLost(self,reason):26         user = self.lines[0]27         status = self.lines[1]28         self.factory.setUser(user, status)29 30 class FingerService(service.Service):31     def __init__(self, users):32         self.users = users33 34     def getUser(self, user):35         return defer.succeed(self.users.get(user, b"No such user"))36 37     def setUser(self, user, status):38         self.users[user] = status39 40     def getFingerFactory(self):41         f = protocol.ServerFactory()42         f.protocol = FingerProtocol43         f.getUser = self.getUser44         return f45 46     def getFingerSetterFactory(self):47         f = protocol.ServerFactory()48         f.protocol = FingerSetterProtocol49         f.setUser = self.setUser50         return f51 52 application = service.Application('finger', uid=1, gid=1)53 f = FingerService({b'moshez': b'Happy and well'})54 serviceCollection = service.IServiceCollection(application)55 strports.service("tcp:79", f.getFingerFactory()56                    ).setServiceParent(serviceCollection)57 strports.service("tcp:1079", f.getFingerSetterFactory()58                    ).setServiceParent(serviceCollection)

简化了代码,在一个服务中使用两个协议 1 from twisted.application import service, strports 2 from twisted.internet import protocol, reactor, defer

3 from twisted.protocols import basic 4  5 class FingerProtocol(basic.LineReceiver): 6     def lineReceived(self, user): 7         d = self.factory.getUser(user) 8  9         def onError(err):10             return b'Internal error in server'11         d.addErrback(onError)12 13         def writeResponse(message):14             self.transport.write(message + b'\r\n')15             self.transport.loseConnection()16         d.addCallback(writeResponse)17 18 19 class FingerService(service.Service):20     def __init__(self, filename):21         self.users = {}22         self.filename = filename23 24     def _read(self):25         with open(self.filename, "rb") as f:26             for line in f:27                 user, status = line.split(b':', 1)28                 user = user.strip()29                 status = status.strip()30                 self.users[user] = status        #这里每30秒刷新一次31         self.call = reactor.callLater(30, self._read)32 33     def startService(self):34         self._read()35         service.Service.startService(self)36 37     def stopService(self):38         service.Service.stopService(self)39         self.call.cancel()40 41     def getUser(self, user):42         return defer.succeed(self.users.get(user, b"No such user"))43 44     def getFingerFactory(self):45         f = protocol.ServerFactory()46         f.protocol = FingerProtocol47         f.getUser = self.getUser48         return f49 50 51 application = service.Application('finger', uid=1, gid=1)52 f = FingerService('/etc/users')53 finger = strports.service("tcp:79", f.getFingerFactory())54 55 finger.setServiceParent(service.IServiceCollection(application))56 f.setServiceParent(service.IServiceCollection(application))

这个版本在一个集中管理的文件中读取消息,而且进行缓存,每30秒刷新一次

在网上进行宣布

也有其他的服务可以产生这种有效的通信。举个例子,在twisted.web里,这个类本身不做基类,而是被给一个资源,表示通过URL可用的树形资源。这个层级结构由Site动态地覆盖,通过getChild。

为了把它集合到Finger应用程序里,我们设置一个新的TCPservice,这个服务器调用Site的心函数来获取资源。

1 from twisted.application import service, strports 2 from twisted.internet import protocol, reactor, defer 3 from twisted.protocols import basic 4 from twisted.web import resource,server,static 5 import cgi 6  7 class FingerProtocol(basic.LineReceiver): 8     def lineReceived(self, user): 9         d = self.factory.getUser(user)10 11         def onError(err):12             return b'Internal error in server'13         d.addErrback(onError)14 15         def writeResponse(message):16             self.transport.write(message + b'\r\n')17             self.transport.loseConnection()18         d.addCallback(writeResponse)19 20 class FingerResource(resource.Resource):21     def __init__(self,users):22         self.users=users23         #继承基类的__init__24         super(FingerResource, self).__init__()25     def getChild(self, path, request):26         messageValue=self.users.get(path)27         if messageValue:28             messageValue=messageValue.decode('ascii')29         if path:30             path=path.decode('ascii')31         if messageValue is not None:32             messageValue=cgi.escape(messageValue)33             text="

{}

{}

".format(path,messageValue)34 else:35 text="

{}

no such path

".format(path)36 text=text.encode('ascii')37 return static.Data(text,'text/html')38 class FingerService(service.Service):39 def __init__(self,filename):40 self.filename=filename41 self.users={}42 def _read(self):43 self.users.clear()44 with open(self.filename,'rb')as f:45 for line in f:46 user,status=line.split(b":",1)47 user=user.strip()48 status=status.strip()49 self.users[user]=status50 self.call=reactor.callLater(30,self._reaf)51 def getUser(self,user):52 return defer.succeed(self.users.get(user,b'no such user'))53 def getFingerFactory(self):54 f=protocol.ServerFactory()55 f.protocol=FingerProtocol56 f.getUser=self.getUser57 return f58 def getResource(self):59 f=FingerResource(self.users)60 return f61 def startService(self):62 self._read()63 service.Service.stopService(self)64 def stopService(self):65 service.Service.stopService(self)66 self.call.cancel()67 application=service.Application('finger',uid=1,gid=1)68 f=FingerService('/finger')69 serviceCollection=service.IServiceCollection(application)70 f.setServiceParent(serviceCollection)71 strports.service("tcp:79",f.getFingerFactory()72 ).setServiceParent(serviceCollection)73 strports.service("tcp:8000",server.Site(f.getResource())74 ).setServiceParent(serviceCollection)

在IRC上宣布

IRC客户端通常很像服务器,相应来自网咯的时间。客户服务奖确保切断的连接重新建立,用了很常见的指数退避。

1 from twisted.application import internet, service, strports  2 from twisted.internet import protocol, reactor, defer, endpoints  3 from twisted.words.protocols import irc  4 from twisted.protocols import basic  5 from twisted.web import resource, server, static  6   7 import cgi  8   9 class FingerProtocol(basic.LineReceiver): 10     def lineReceived(self, user): 11         d = self.factory.getUser(user) 12  13         def onError(err): 14             return b'Internal error in server' 15         d.addErrback(onError) 16  17         def writeResponse(message): 18             self.transport.write(message + b'\r\n') 19             self.transport.loseConnection() 20         d.addCallback(writeResponse) 21  22  23 class IRCReplyBot(irc.IRCClient): 24     def connectionMade(self): 25         self.nickname = self.factory.nickname 26         irc.IRCClient.connectionMade(self) 27  28     def privmsg(self, user, channel, msg): 29         user = user.split('!')[0] 30         if self.nickname.lower() == channel.lower(): 31             d = self.factory.getUser(msg.encode("ascii")) 32  33             def onError(err): 34                 return b'Internal error in server' 35             d.addErrback(onError) 36  37             def writeResponse(message): 38                 message = message.decode("ascii") 39                 irc.IRCClient.msg(self, user, msg + ': ' + message) 40             d.addCallback(writeResponse) 41  42  43 class FingerService(service.Service): 44     def __init__(self, filename): 45         self.filename = filename 46         self.users = {} 47  48     def _read(self): 49         self.users.clear() 50         with open(self.filename, "rb") as f: 51             for line in f: 52                 user, status = line.split(b':', 1) 53                 user = user.strip() 54                 status = status.strip() 55                 self.users[user] = status 56         self.call = reactor.callLater(30, self._read) 57  58     def getUser(self, user): 59         return defer.succeed(self.users.get(user, b"No such user")) 60  61     def getFingerFactory(self): 62         f = protocol.ServerFactory() 63         f.protocol = FingerProtocol 64         f.getUser = self.getUser 65         return f 66  67     def getResource(self): 68         def getData(path, request): 69             user = self.users.get(path, b"No such users 

usage: site/user") 70 path = path.decode("ascii") 71 user = user.decode("ascii") 72 text = '

{}

{}

'.format(path, user) 73 text = text.encode("ascii") 74 return static.Data(text, 'text/html') 75 76 r = resource.Resource() 77 r.getChild = getData 78 return r 79 80 def getIRCBot(self, nickname): 81 f = protocol.ClientFactory() 82 f.protocol = IRCReplyBot 83 f.nickname = nickname 84 f.getUser = self.getUser 85 return f 86 87 def startService(self): 88 self._read() 89 service.Service.startService(self) 90 91 def stopService(self): 92 service.Service.stopService(self) 93 self.call.cancel() 94 95 96 application = service.Application('finger', uid=1, gid=1) 97 f = FingerService('/etc/users') 98 serviceCollection = service.IServiceCollection(application) 99 f.setServiceParent(serviceCollection)100 strports.service("tcp:79", f.getFingerFactory()101 ).setServiceParent(serviceCollection)102 strports.service("tcp:8000", server.Site(f.getResource())103 ).setServiceParent(serviceCollection)104 internet.ClientService(105 endpoints.clientFromString(reactor, "tcp:irc.freenode.org:6667"),106 f.getIRCBot('fingerbot')).setServiceParent(serviceCollection)

 

转载于:https://www.cnblogs.com/losenine/p/10084572.html

你可能感兴趣的文章
[简讯]phpMyAdmin项目已迁移至GitHub
查看>>
转载 python多重继承C3算法
查看>>
【题解】 bzoj1597: [Usaco2008 Mar]土地购买 (动态规划+斜率优化)
查看>>
css文本溢出显示省略号
查看>>
git安装和简单配置
查看>>
面向对象:反射,双下方法
查看>>
鼠标悬停提示文本消息最简单的做法
查看>>
课后作业-阅读任务-阅读提问-2
查看>>
面向对象设计中private,public,protected的访问控制原则及静态代码块的初始化顺序...
查看>>
fat32转ntfs ,Win7系统提示对于目标文件系统文件过大解决教程
查看>>
Awesome Adb——一份超全超详细的 ADB 用法大全
查看>>
shell cat 合并文件,合并数据库sql文件
查看>>
Android 将drawable下的图片转换成bitmap、Drawable
查看>>
介绍Win7 win8 上Java环境的配置
查看>>
移动、联通和电信,哪家的宽带好,看完你就知道该怎么选了!
查看>>
Linux设置环境变量的方法
查看>>
构建自己的项目管理方案
查看>>
利用pca分析fmri的生理噪声
查看>>
div水平居中且垂直居中
查看>>
epoll使用具体解释(精髓)
查看>>