zoukankan      html  css  js  c++  java
  • 游戏服务器学习笔记 4———— master 模块介绍

    (模块的介绍方法都是先说大体功能,在捡一些细节详细讨论。)

    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 sername in 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,透明代理)

  • 相关阅读:
    Debian 9/Ubuntu 18添加rc.local开机自启的方法
    第一次使用Debian9所遇到的问题
    Open-Falcon注册时点击Sign up按钮没反应
    使用VMware虚拟机里的Ubuntu18.04部署RAID 10磁盘阵列
    Ubuntu18.04下Ansible的基本使用
    Go语言求水仙花数(for循环)
    自研模块加载器(四) 模块资源定位-异步加载
    自研模块加载器(三) module模块构造器设计-模块数据初始化
    自研模块加载器(二) 加载器结构与设计导论
    自研模块加载器(一) 模块系统概述与自定义模块规范书写规定
  • 原文地址:https://www.cnblogs.com/fuhaots2009/p/3508875.html
Copyright © 2011-2022 走看看