实际上这章压根不需要我来说,twisted官网的Doc里面有专门介绍的章节。写的非常详细。

http://twistedmatrix.com/documents/current/core/howto/index.html

我只能肤浅的说说firefly里面对PB的运用。

首先firefly使用PB的目的是实现各个模块之间的通信,做到“分布式”,逻辑分离。

比如master模块专门负责控制,gate做分发,game1做游戏逻辑,net做网络相关。如果不用twisted.pb的话,我们就要自己写复杂socket逻辑,来实现各个节点之间的数据通讯。

现在有了twisted.pb,“妈妈再也不用担心我的学习”。

Firefly所有的分布式相关代码都在firefly/distribute/目录

__init__.py  child.py    manager.py   node.py      reference.py root.py

root.py 实现PB的server功能

node.py 实现PB的client功能。

child.py 每个client连接上root都会初始化一个child来保存该client的相关信息,并且将这些child通过manager来管理。

manager.py 管理root的child,通过一个字典self._childs = {},实现一个增删改的小管理器。

reference.py 如果你看了前面twisted官网的介绍就会知道,node只要实例化一个 pb.Referenceable 类,并把它传递给root,那么root就能够把这个pb.Referenceble当成句柄来远程调用root函数。

前面章节提到master模块实现了一个PBRoot作为server等待client端的连接。我们这里先拿DB模块来说明。(DB模块的其它功能,和我改写的部分后面会详细介绍。)

master模块里面实现的代码如下(这个是我改过的代码,稍后上传git):

38     def__startRoot(self):

39         GlobalObject().root = PBRoot("rootservice")

40         reactor.listenTCP(self.rootport,BilateralFactory(GlobalObject().root))

其中PBRoot类有2个关键函数。

defremote_register(self,name,transport):

"""设置代理通道

@param addr:(hostname,port)hostname 根节点的主机名,根节点的端口

"""

log.msg('node [%s]registerdd' % name)

child =Child(name,transport)

# child.setTransport(transport)

self.childsmanager.addChild(child)

defremote_callTarget(self,command,*args,**kw):

"""远程调用方法

@param commandId:int 指令号

@param data: str 调用参数

"""

data =self.service.callTarget(command,*args,**kw)

return data

remote_register(),这个函数名称被我改了,原先好像叫做remote_takeproxy()。大家理解的角度不一样,原先作者lan可能是认为这个函数的功能是root取得其它模块提供给他的代理。我认为,这个函数是其它函数注册到root。

PB的约定是,本地函数起名remote_xxx(),远程函数调用直接callremote(“XXX”),所以按照习惯,大家看到的remote_xxx()函数都是提供给对方调用的。

另外,这里补充一下,twisted官网提到,PB一旦建立好连接以后,server和client的行为其实是对等的,大家权限,调用都一样。

再看一下上面2个函数,regist可以看出就是用child类来保存一下注册过来的client。callTarget函数就是通过services来执行远程的调用命令。具体的callTarget逻辑后面有空再介绍。

下面 我们看client端,拿DB来说。和master模块不一样,其它模块,包括dbfront,启动过程依赖配置文件config.json的设定后面详细讨论。这里我们只关注PB相关。

下面的代码取自firefly/server/server.py

(实际上已经被我整理过,但具体代码逻辑还是一样)

59         if masterconf: #这里一定为True

60             masterport = masterconf.get('rootport')

61             self.master_remote =RemoteObject(servername)

62             addr = ('localhost',masterport)

63             self.master_remote.connect(addr)

64             GlobalObject().masterremote =self.master_remote

这里的RemoteObject类的初始化__init__函数如下:(firefly/distribute/node.py)

def__init__(self,name):

23         """初始化远程调用对象

24         @param port: int 远程分布服的端口号

25         @param rootaddr: 根节点服务器地址

26         """

27         self._name = name

28         self._factory = pb.PBClientFactory()

29         self._reference = ProxyReference()#这个就是pb.Referenceable的子类

30         self._addr = None

可以看出我们实现了一个RemoteObject类,这个类包括了pb.PBClientFactory 和pb.Referenceble。在line 63对应的代码里面,我们connect的时候

reactor.connectTCP(addr[0], addr[1], self._factory)

就建立了一个root和node的连接。然后再调用下面的函数。

def register(self):

"""把本节点注册到RootNode,并且向RootNode发送代理通道对象

"""

deferedRemote =self._factory.getRootObject()#取得root的调用句柄。

deferedRemote.addCallback(callBack,'register',self._name,self._reference)#callBack函数会调用pb.callRemote()

这个函数就2行,第一行是twisted.pb的client取得root的句柄,有了这个句柄,我们就能够通过callRemote来调用root的相应函数。这里调用的regist,对应root的remote_regist()函数,并且把自己的referenceble传递给root,那么后面root就可以通过这个referenceble来调用自己(node)了。

OK,firefly对twisted.pb的封装和实现就介绍到这里。PB的介绍先告一段落,由于俺能力实在有限,可能大家还没有看清楚。

别担心,我们后面接着介绍各个模块的过程中也会穿插firefly的PB运用的细节介绍。之后如果有时间精力我们再对各个模块中运用PB实现的功能做个总结。

游戏服务器学习笔记 5———— twisted Perspective Broker 透明代理的更多相关文章

  1. 游戏服务器学习笔记 4———— master 模块介绍

    (模块的介绍方法都是先说大体功能,在捡一些细节详细讨论.) master 类很简单,就3个函数,一个init,设置配置信息,并调用masterapp,然后还有一个循环启动子进程的start函数. 这里 ...

  2. 游戏服务器学习笔记 3———— firefly 的代码结构,逻辑

    注:以下所有代码都是拿暗黑来举例,由于本人能力有限很多地方还没有看透彻,所以建议大家只是参考.有不对的地方非常欢迎指正. 一.结构     系统启动命令是,python statmaster.py,启 ...

  3. DirectX 11游戏编程学习笔记之8: 第6章Drawing in Direct3D(在Direct3D中绘制)(习题解答)

            本文由哈利_蜘蛛侠原创,转载请注明出处.有问题欢迎联系2024958085@qq.com         注:我给的电子版是700多页,而实体书是800多页,所以我在提到相关概念的时候 ...

  4. 【Visual C++】游戏编程学习笔记之四:透明动画实现

    本系列文章由@二货梦想家张程 所写,转载请注明出处. 本文章链接:http://blog.csdn.net/terence1212/article/details/44224963 作者:ZeeCod ...

  5. 【Visual C++】游戏编程学习笔记之八:鼠标输入消息(小demo)

     本系列文章由@二货梦想家张程 所写,转载请注明出处. 作者:ZeeCoder  微博链接:http://weibo.com/zc463717263 我的邮箱:michealfloyd@126.c ...

  6. 【Visual C++】游戏编程学习笔记之七:键盘输入消息

     本系列文章由@二货梦想家张程 所写,转载请注明出处. 作者:ZeeCoder  微博链接:http://weibo.com/zc463717263 我的邮箱:michealfloyd@126.c ...

  7. 【Visual C++】游戏编程学习笔记之六:多背景循环动画

    本系列文章由@二货梦想家张程 所写,转载请注明出处. 本文章链接:http://blog.csdn.net/terence1212/article/details/44264153 作者:ZeeCod ...

  8. DirectX 11游戏编程学习笔记之6: 第5章The Rendering Pipeline(渲染管线)

            本文由哈利_蜘蛛侠原创,转载请注明出处.有问题欢迎联系2024958085@qq.com         注:我给的电子版是700多页,而实体书是800多页,所以我在提到相关概念的时候 ...

  9. C++游戏服务器编程笔记 IP详解

    C++游戏服务器编程笔记 IP详解 IP详解 INTERNET的历史 上世纪60年底起源于美国 1992年,Internet上的主机超过了100万台 现在已经是现代文明人的必需品    TCP/IP的 ...

随机推荐

  1. (原创)关于FFmpeg的一些有关的初始化默认值的问题

    最近手头上要做一个媒体格式分析库,能解析文件,流的视频格式,编码格式等一些重要的视频参数能进行尽量多的提取.当我们做媒体相关方面的东西,自然而然就会想到FFmpeg这个强大的开源媒体库,所以我们肯定会 ...

  2. llinux 环境安装编译 nginx (源码安装包)

    简介: Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行.由俄罗斯的程序设计师Igor Sysoev所开发,供俄国 ...

  3. 每天一个linux命令:traceroute命令

    通过traceroute我们可以知道信息从你的计算机到互联网另一端的主机是走的什么路径.当然每次数据包由某一同样的出发点(source)到达某一同样的目的地(destination)走的路径可能会不一 ...

  4. C# 中base和this关键字

    base: 用于在派生类中实现对基类公有或者受保护成员的访问,但是只局限在构造函数.实例方法和实例属性访问器中. MSDN中小结的具体功能包括: ()调用基类上已被其他方法重写的方法. ()指定创建派 ...

  5. Spring简单集成Redis

  6. git基于历史commit创建分支

    基于以前的commit创建一个分支 步骤: 1.确定需要取出版本的commit值 git log 2.基于该commit创建分支 git branch <branch name> < ...

  7. u3d一个GameObject绑定两个AudioSource

    u3d 一个GameObject绑定两个AudioSource  ,使他们分别播放,并控制 using UnityEngine; using System.Collections; public cl ...

  8. iOS: 自动增高的 textView

    如 iPhone 内应用“信息”的输入框一样,输入文字过多或者输入换行,输入框可以随着内容自动变化.主要是计算内容的尺寸并相应更改输入框的frame.具体表现在: 更改输入框的 frame.origi ...

  9. 如何解析oracle执行计划

    要执行任何SQL语句,Oracle 必须推导出一个“执行计划”.查询的执行计划是 Oracle 将如何实现数据的检索,以满足给定 SQL 语句的描述.它只不过是其中包含的步骤及它们之间关系的顺序树.执 ...

  10. Eclipse------导入项目后出现Java compiler level does not match the version of the installed Java project facet

    报错信息:Java compiler level does not match the version of the installed Java project facet 解决方法: 1.点击工具 ...