firefly的rpc。。
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。。的更多相关文章
- 从RPC开始(一)
这是一篇关于纯C++RPC框架的文章.所以,我们先看看,我们有什么? 1.一个什么都能干的C++.(前提是,你什么都干了) 2.原始的Socket接口,还是C API.还得自己去二次封装... 3.C ...
- RPC 使用中的一些注意点
最近线上碰到一点小问题,分析其原因发现是出在对 RPC 使用上的一些细节掌握不够清晰导致.很多时候我们做业务开发会把 RPC 当作黑盒机制来使用,但若不对黑盒的工作原理有个基本掌握,也容易犯一些误用的 ...
- 谈谈如何使用Netty开发实现高性能的RPC服务器
RPC(Remote Procedure Call Protocol)远程过程调用协议,它是一种通过网络,从远程计算机程序上请求服务,而不必了解底层网络技术的协议.说的再直白一点,就是客户端在不必知道 ...
- 游戏编程系列[1]--游戏编程中RPC协议的使用[3]--体验
运行环境,客户端一般编译为.Net 3.5 Unity兼容,服务端因为用了一些库,所以一般为4.0 或往上.同一份代码,建立拥有2个项目.客户端引用: WindNet.Client服务端引用: OpL ...
- python通过protobuf实现rpc
由于项目组现在用的rpc是基于google protobuf rpc协议实现的,所以花了点时间了解下protobuf rpc.rpc对于做分布式系统的人来说肯定不陌生,对于rpc不了解的童鞋可以自行g ...
- spider RPC入门指南
本部分将介绍使用spider RPC开发分布式应用的客户端和服务端. spider RPC中间件基于J2SE 8开发,因此需要确保服务器上安装了JDK 8及以上版本,不依赖于任何额外需要独立安装和配置 ...
- Netty实现高性能RPC服务器优化篇之消息序列化
在本人写的前一篇文章中,谈及有关如何利用Netty开发实现,高性能RPC服务器的一些设计思路.设计原理,以及具体的实现方案(具体参见:谈谈如何使用Netty开发实现高性能的RPC服务器).在文章的最后 ...
- 基于Netty打造RPC服务器设计经验谈
自从在园子里,发表了两篇如何基于Netty构建RPC服务器的文章:谈谈如何使用Netty开发实现高性能的RPC服务器.Netty实现高性能RPC服务器优化篇之消息序列化 之后,收到了很多同行.园友们热 ...
- Redola.Rpc 的一个小目标
Redola.Rpc 的一个小目标 Redola.Rpc 的一个小目标:20000 tps. Concurrency level: 8 threads Complete requests: 20000 ...
随机推荐
- EasyUI 添加tab页(iframe方式)
function addTab(title, href,icon){ var tt = $('#tabs'); if (tt.tabs('exists', title)){//如果tab已经存在,则选 ...
- ccr1
Concurrency and Coordination Runtime Jeffrey Richter Code download available at:ConcurrentAffairs200 ...
- 交易的成功 = 60%的资金管理 + 40%出入场信号 zt
交易的成功 = 60%的资金管理 + 40%出入场信号. 资金管理 = 60%的风险分散 + 40%的适度重或轻仓. 出入场信号 = 60%的出场信号 + 40%的入场信号. 交易的成功 = 36 ...
- Jmeter初步使用--Jmeter安装与使用
由于jmeter是开源的性能测试工具,但是使用的人较少,网络上相关资料不全面,需要自己去揣摩,因此,小编就把自己在用Jmeter时的一些小结总结出来.而loadrunner工具是商业软件,网上通常都是 ...
- CodeForce---Educational Codeforces Round 3 USB Flash Drives (水题)解题报告
对于这题明显是用贪心算法来解决问题: 下面贴出笔者的代码: #include<cstdio> #include<iostream> #include<algorithm& ...
- 用JDK自带的工具生成客户端调用Webservice的代码
JAVA下客户端调用Webservice代码简直是让人心生畏惧,今日尝试,做记录如下,参考网上的众多解决方案,下面这种方式是比较简单的. 在jdk的bin目录下有一个wsimport.exe的工具,使 ...
- bzoj 1834 [ZJOI2010]network 网络扩容(MCMF)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1834 [题意] 给定一个有向图,每条边有容量C,扩容费用W,问最大流和使容量增加K的最 ...
- HDU-4639 Hehe 简单DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4639 简单递推题,呵呵,不多说... //STATUS:C++_AC_15MS_272KB #incl ...
- HDU-4616 Game 树形DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4616 比较典型的树形DP题目,f[u][j][k]表示以点u为子树,经过 j 个陷阱的最大值,其中k= ...
- JS代码片段
1. 对比cookie // cookie array function getCookieArrayByStr(str) { var cookies = str.split("; &quo ...