pomelo的rpc实现原理

来源:互联网 发布:公安部网络监察局 编辑:程序博客网 时间:2024/06/05 04:49

先从客户端这边说起。当服务器启动之后,会收到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


0 0
原创粉丝点击