firefly使用了twisted的pb 来实现rpc:

http://twistedmatrix.com/documents/current/core/howto/pb-usage.html

服务端
#!/usr/bin/env python # Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details. from twisted.spread import pb
from twisted.internet import reactor class One(pb.Root):
def remote_takeTwo(self, two):
print "received a Two called", two
print "telling it to print(12)"
two.callRemote("print", 12) reactor.listenTCP(8800, pb.PBServerFactory(One()))
reactor.run() 客户端 #!/usr/bin/env python # Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details. from twisted.spread import pb
from twisted.internet import reactor class Two(pb.Referenceable):
def remote_print(self, arg):
print "Two.print() called with", arg def main():
two = Two()
factory = pb.PBClientFactory()
reactor.connectTCP("localhost", 8800, factory)
def1 = factory.getRootObject()
def1.addCallback(got_obj, two) # hands our 'two' to the callback
reactor.run() def got_obj(obj, two):
print "got One:", obj
print "giving it our two"
obj.callRemote("takeTwo", two) main()

  

1.客户端通过factory.getRootObject() 获取def,并增加回调函数。其第一个参数为pb.Root(未证实),然后借助callRemote方法条用服务端的东西

2.可以在客户端首次连接的时候,将客户端的Referenceable传给服务端。。服务端进行保存。。之后需要像客户端发送消息的时候。。只要使用客户端的callRemote就OK了

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当成句柄来远程调用client的函数。

下面我们看看firefly的实现。

1.实例化客户端node,实例了客户端工厂,_reference和name

2.客户端建立连接:node.connect ,并条用了服务端的takeProxy。建立了通道

def callRemote(obj,funcName,*args,**kw):
'''远程调用
@param funcName: str 远程方法
'''
return obj.callRemote(funcName, *args,**kw) 。。。。。。
。。。。。。
def takeProxy(self):
'''像远程服务端发送代理通道对象
'''
deferedRemote = self._factory.getRootObject()
deferedRemote.addCallback(callRemote,'takeProxy',self._name,self._reference)

2.服务端的takeProxy。根据第一次传过来的客户端名称和reference实例化了child,并保存到childManage中

3.执行了首次连接处理。doChildConnect。。请看rootapp.py.如果不看这里你一定会很奇怪,gate的root怎么和其他的server连接起来的。

def _doChildConnect(name,transport):
"""当server节点连接到master的处理
"""
server_config = GlobalObject().json_config.get('servers',{}).get(name,{})
remoteport = server_config.get('remoteport',[])
child_host = transport.broker.transport.client[0]
root_list = [rootport.get('rootname') for rootport in remoteport]
GlobalObject().remote_map[name] = {"host":child_host,"root_list":root_list}
#通知有需要连的node节点连接到此root节点
for servername,remote_list in GlobalObject().remote_map.items():
remote_host = remote_list.get("host","")
remote_name_host = remote_list.get("root_list","")
if name in remote_name_host:
GlobalObject().root.callChild(servername,"remote_connect",name,remote_host)
#查看当前是否有可供连接的root节点
master_node_list = GlobalObject().remote_map.keys()
for root_name in root_list:
if root_name in master_node_list:
root_host = GlobalObject().remote_map[root_name]['host']
GlobalObject().root.callChild(name,"remote_connect",root_name,root_host)

4.服务端调用客户端。root.callChildByName.会在childManager中找到child并使用其中的reference,最终条用代码为:ProxyReference(pb.Referenceable):中的

    def remote_callChild(self, command,*arg,**kw):
'''代理发送数据
'''
return self._service.callTarget(command,*arg,**kw)

5.客户端条用,服务端使用,node.callRemote..其中最终使用的方法为:root.py中的。

 def remote_callTarget(self,command,*args,**kw):
'''远程调用方法
@param commandId: int 指令号
@param data: str 调用参数
'''
data = self.service.callTarget(command,*args,**kw)
return data

6.从上可以看到。。使用service的意义何在了。。。

firefly的rpc。。的更多相关文章

  1. 从RPC开始(一)

    这是一篇关于纯C++RPC框架的文章.所以,我们先看看,我们有什么? 1.一个什么都能干的C++.(前提是,你什么都干了) 2.原始的Socket接口,还是C API.还得自己去二次封装... 3.C ...

  2. RPC 使用中的一些注意点

    最近线上碰到一点小问题,分析其原因发现是出在对 RPC 使用上的一些细节掌握不够清晰导致.很多时候我们做业务开发会把 RPC 当作黑盒机制来使用,但若不对黑盒的工作原理有个基本掌握,也容易犯一些误用的 ...

  3. 谈谈如何使用Netty开发实现高性能的RPC服务器

    RPC(Remote Procedure Call Protocol)远程过程调用协议,它是一种通过网络,从远程计算机程序上请求服务,而不必了解底层网络技术的协议.说的再直白一点,就是客户端在不必知道 ...

  4. 游戏编程系列[1]--游戏编程中RPC协议的使用[3]--体验

    运行环境,客户端一般编译为.Net 3.5 Unity兼容,服务端因为用了一些库,所以一般为4.0 或往上.同一份代码,建立拥有2个项目.客户端引用: WindNet.Client服务端引用: OpL ...

  5. python通过protobuf实现rpc

    由于项目组现在用的rpc是基于google protobuf rpc协议实现的,所以花了点时间了解下protobuf rpc.rpc对于做分布式系统的人来说肯定不陌生,对于rpc不了解的童鞋可以自行g ...

  6. spider RPC入门指南

    本部分将介绍使用spider RPC开发分布式应用的客户端和服务端. spider RPC中间件基于J2SE 8开发,因此需要确保服务器上安装了JDK 8及以上版本,不依赖于任何额外需要独立安装和配置 ...

  7. Netty实现高性能RPC服务器优化篇之消息序列化

    在本人写的前一篇文章中,谈及有关如何利用Netty开发实现,高性能RPC服务器的一些设计思路.设计原理,以及具体的实现方案(具体参见:谈谈如何使用Netty开发实现高性能的RPC服务器).在文章的最后 ...

  8. 基于Netty打造RPC服务器设计经验谈

    自从在园子里,发表了两篇如何基于Netty构建RPC服务器的文章:谈谈如何使用Netty开发实现高性能的RPC服务器.Netty实现高性能RPC服务器优化篇之消息序列化 之后,收到了很多同行.园友们热 ...

  9. Redola.Rpc 的一个小目标

    Redola.Rpc 的一个小目标 Redola.Rpc 的一个小目标:20000 tps. Concurrency level: 8 threads Complete requests: 20000 ...

随机推荐

  1. js 动态计算折扣后总价格

    <script type="text/javascript"> <!---计算折扣后的总价格---> function outtotalprice(i) { ...

  2. HTML5 离线功能介绍

    HTML5 是目前正在讨论的新一代 HTML 标准,它代表了现在 Web 领域的最新发展方向.在 HTML5 标准中,加入了新的多样的内容描述标签,直接支持表单验证.视频音频标签.网页元素的拖拽.离线 ...

  3. Java [leetcode 16] 3Sum Closest

    题目描述: Given an array S of n integers, find three integers in S such that the sum is closest to a giv ...

  4. MyEclipse/Eclipse导入sun.misc.BASE64Encoder jar包步骤

    1.右键项目 -->Properties -->Java Bulid Path-> Libraries -->JRE System Library-->Access ru ...

  5. GRIB格式转换心得(转自博客:http://windforestwing.blog.163.com/blog/static/19545412007103084743804/)

    1.wgrib的使用 在cmd命令行下键入wgrib后即可察看wgrib相关命令参数,简要介绍如下: l        Inventory/diagnostic–output selections 详 ...

  6. 自定义Sharepoint的登陆页面

    转:http://www.cnblogs.com/jecoso/archive/2008/05/25/1207151.html 原文作者:Damon Armstrong 原文地址:http://www ...

  7. [转] Symbol对象

    GIS中的离散实体有三种:点.线.面,在ArcEngine中用三种符号对应表示,分别是:MarkSymbol.LineSymbol和FillSymbol.此外还有TextSymbol用于文字标注,3D ...

  8. lightoj 1019

    裸的最短路 dijkstra #include<cstdio> #include<string> #include<cstring> #include<ios ...

  9. REST API TESTING

    在敏捷开发过程中 每隔两周就是一个sprint,,, 在上个sprint中,任务就是REST API TESTING 因为以前没做过API 测试,不懂,然后经过询问查找 终于知道,需要发送请求,然后获 ...

  10. python 网络编程 (二)---异常

    异常 python的socket模块实际上定义了4种可能出现的异常: 1)与一般I/O 和通信问题有关的socket.error; 2)与查询地址信息有关的socket.gaierror; 3)与其他 ...