您的位置:首页 > 其它

pomelo的rpc实现原理

2015-04-14 19:00 260 查看
先从客户端这边说起。当服务器启动之后,会收到addServers消息(即后启动的服务器发来的消息)。

看看proxy.js中的收到addServers后的处理:

pro.addServers = function(servers) {
if (!servers || !servers.length) {
return;
}

genProxies(this.client,this.app, servers);
this.client.addServers(servers);
};



client.addServers主要用于加入server的信息,主要是用于生成mailbox,建立于远程服务器的连接,用于实际数据的发送。

genProxies主要是从其他服务器发来的消息servers中提取出其他服务器的rpc方法,主要是remote目录下提供的rpc接口。

var genProxies =function(client, app, sinfos) {
var item;
for (var i = 0, l = sinfos.length; i < l; i++) {
item = sinfos[i];
if (hasProxy(client, item)) {
continue;
}
client.addProxies(getProxyRecords(app,item));
}
};

getProxyRecords最终组织了sinfos的信息为records,作为参数传递给pomelo-rpc的addProxies方法。

在pomelo-rpc的client中通过一系列的调用

addProxies-》addProxy-》generateProxy-》insertProxy

最后看看insertProxy函数

var insertProxy= function(proxies, namespace, serverType, proxy) {

proxies[namespace] = proxies[namespace] ||{};

proxies[namespace][serverType] = proxy;//访问就是xx.xx这样去访问app.rpc.xx.xx/app.sysrpc.xx.xx

};

回头看看proxy.js的afterStart函数

pro.afterStart = function(cb) {
var self =
this
;
this.app.__defineGetter__('rpc',function() {
return self.client.proxies.user;
});
this.app.__defineGetter__('sysrpc',function() {
return self.client.proxies.sys;
});
this.app.set('rpcInvoke',this.client.rpcInvoke.bind(this.client),true);
this.client.start(cb);
};



所以调用this.app.rpc.xx.xx 实际上等价于self.client.proxies.user.xx.xx。同理还有sysRpc和直接rpc。

Rpc调用通过utils/proxy.js最终会调用proxyCB,之后通过this._station.dispatch将rpc调用请求发送出去。

总结一下,主要就是依靠了其他服务器启动时发送的servers消息,根据这些信息使用pomelo-rpc/pomelo-loader来载入远程服务器的remoteHandler的js文件路径,并缓存这些rpc服务接口。当client发起rpc调用之后,通过mail将消息发送给对方,对方收到消息后,解析报文,调用相应的rpc接口进行逻辑处理。在给调用方返回结果。

这里对Pomelo-loader解析目录的js文件接口做了小例子:

有这样的目录

mock-remote/area/

|-- addOneRemote.js

|-- addThreeRemote.js

|-- some-sub-dir

| `-- someRemote.js

`-- whoAmIService.js



1 var Loader =require("../");//实质就是pomelo-loader模块

2

3 var res =Loader.load("./mock-remote/area");

4

5 console.log(res);

输出结果:

{ addOneRemote: { doService: [Function], doAddTwo: [Function] },

addThreeRemote: { doService:[Function] },

whoAmIRemote: { doService:[Function], name: 'whoAmIRemote' } }

可以看到 除了mock-remote/area/子目录下的js文件,其他pomelo-loader都载入了。

更多的信息可以参见:
http://blog.csdn.net/fjslovejhl/article/details/10964613
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: