(子產品的介紹方法都是先說大體功能,在撿一些細節詳細讨論。)
master 類很簡單,就3個函數,一個init,設定配置資訊,并調用masterapp,然後還有一個循環啟動子程序的start函數。
這裡隻有masterapp函數值得我們關注。
代碼如下:
36 defmasterapp(self):
37 config = json.load(open(self.configpath,'r'))
38 mastercnf = config.get('master')
39 rootport = mastercnf.get('rootport')
40 webport = mastercnf.get('webport')
41 masterlog = mastercnf.get('log')
42 self.root = PBRoot()
43 rootservice = services.Service("rootservice")
44 self.root.addServiceChannel(rootservice)
45 self.webroot = vhost.NameVirtualHost()
46 self.webroot.addHost('0.0.0.0','./')
47 GlobalObject().root = self.root
48 GlobalObject().webroot = self.webroot
49 ifmasterlog:
50 log.addObserver(loogoo(masterlog))#日志處理
51 log.startLogging(sys.stdout)
52 import webapp
53 import rootapp
54 reactor.listenTCP(webport,DelaySite(self.webroot))
55 reactor.listenTCP(rootport,BilateralFactory(self.root))
實際上我不喜歡這種編碼風格,感覺有點亂,有些過度使用import和python的修飾符。
仔細看,這裡首先通過config.json讀取配置資訊,然後根據配置資訊,起一個pb.root,和一個webserver,然後給pb.root 加一個services,這個services類是個非常重要的類,貫穿整個系統。我們下面會詳細介紹它。這裡還通過import webapp 和修飾符@xxx的方法來實作給webserver添加stop 和reload 2個child。實作的功能,我前面其實已經是說過。就是在浏覽器裡面輸入http://localhost:9998/stop或者http://localhost:9998/reload來調用對于的類。具體實作的方法是:
webroot = vhost.NameVirtualHost()
webroot.putChild(cls.__name__, cls()) ;
這個vhost.NameVirtualHost().putChild()函數也是twisted的函數,和前面pb.root一樣,大家如果等不及我後面的解說可以自己google到twisted網站,上面有詳細的doc、samples。
由于看的實在不習慣(可能自己是python、server的新手),是以我就自己按照功能實作改了一下結構,如下,希望大家對比可以更加清晰。(我改動後的所有代碼都會抽空上傳到github。位址為:https://github.com/chenee如果沒有說明我還沒來得及上傳,在等等,或者直接M我要。)
22classMaster:
23 def__init__(self, configpath, mainpath):
24 """
25 """
26 self.configpath = configpath
27 self.mainpath = mainpath
28
29 config = json.load(open(self.configpath,'r'))
30 mastercnf = config.get('master')
31 self.rootport = mastercnf.get('rootport')
32 self.webport = mastercnf.get('webport')
33 self.masterlog = mastercnf.get('log')
34
35 def__startRoot(self):
36 root = PBRoot("rootservice")
37 GlobalObject().root = root
38 reactor.listenTCP(self.rootport,BilateralFactory(root))
39
40
41 def__startWeb(self):
42 webroot = vhost.NameVirtualHost()
43 webroot.addHost('0.0.0.0','./')
44 GlobalObject().webroot = webroot
45 webapp.initWebChildren()
46 reactor.listenTCP(self.webport,DelaySite(webroot))
47
48
49 defstartMaster(self):
50
51 self.__startRoot()
52 self.__startWeb()
53
54 if self.masterlog:
55 log.addObserver(loogoo(self.masterlog))#日志處理
56 log.startLogging(sys.stdout)
57
58 #reactor.run()
59
60 defstartChildren(self):
61 """
62 """
63 print"startchildren ......"
64 config = json.load(open(self.configpath,'r'))
65 sersconf = config.get('servers')
66 for sernamein sersconf.keys():
67 cmds ='python %s %s %s' % (self.mainpath,sername, self.configpath)
68 subprocess.Popen(cmds, shell=True)
69 reactor.run()
我把原先通過addServiceChannel()添加services的過程放到PBRoot類的__init__裡面了,這樣改動也适合後面其它子產品,反正root邏輯上肯定是需要一個services的。而且這個services就是普通services。(後面還會提到一些services的子類)
另外,把原先通過import webapp 加用修飾類實作的putChild()功能,直接寫到一個注冊函數裡面。
45 webapp.initWebChildren()
addToWebRoot(stop)
addToWebRoot(reloadmodule)
改動以後的功能和原先一模一樣,改動後的代碼對我等新手來說可以清晰的看到master子產品的結構
OK,下面我們來看剛才提到的services。用戶端所有的指令最終都是通過services的
callTarget(self,targetKey,*args,**kw) 函數來分發。
比如client端發一條編号為01的指令,或者一條“login”指令,server端到底執行什麼處理函數,就是通過services來實作的,具體實作實際上就是在services類裡面通過
self._targets= {} # Keeps track of targets internally
這個字典來儲存指令ID/名稱 和具體指令實作函數的對應關系。
注冊、和登出這個對應關系的函數為services類的:mapTarget() 、unMapTarget()。
每個子產品(master,gate,net。。。)都有對應的services,但是可能不止一個。
子產品之間提供服務,也是通過實作一個services執行個體,并注冊一批相應處理函數來實作的。
OK,到這裡master基本介紹完畢。
由于master的webserver功能比較簡單,而且和系統的其它子產品基本無關。大家可以通過twisted官網的DOC和sample來了解,我就不贅述了。
API:
http://twistedmatrix.com/documents/10.2.0/api/twisted.web.vhost.NameVirtualHost.html
Twisted Web In 60 Seconds:
https://twistedmatrix.com/documents/current/web/howto/web-in-60/index.html
下篇文章我盡力介紹twisted的PB(Perspective Broker,透明代理)