项目接近尾声,这个周在弄运维相关的一些东西。
运维部门需要一个http服务器,来查询服务器及玩家的一些数据。
在做的过程中考虑的是两个问题:
1 这个http服务器挂在什么地方?
为了不污染pemelo的代码,做了一个httpServer的组件,在gate服务器中加载。
因为其他服务器可能有多个,这样会重复加载httpServer组件,导致端口重复监听。
2 多个area服务器,如何确定rpc调用的路由?
pomelo默认的路由格则如下:
// game-server/node_modules/pomelo/lib/components/proxy.js
var genRouteFun = function() { return function(session, msg, app, cb) { var routes = app.get('__routes__'); if (!routes) { defaultRoute(session, msg, app, cb); return; } var type = msg.serverType, route = routes[type] || routes['default']; if (route) { route(session, msg, app, cb); } else { defaultRoute(session, msg, app, cb); } };};var defaultRoute = function(session, msg, app, cb) { var list = app.getServersByType(msg.serverType); if (!list || !list.length) { cb(new Error('can not find server info for type:' + msg.serverType)); return; } var uid = session ? (session.uid || '') : ''; var index = Math.abs(crc.crc32(uid.toString())) % list.length; utils.invokeCallback(cb, null, list[index].id);};
从代码中可以看到,若没有设置路由规则就调用默认的路由规则。
默认路由规则中,uid决定了所在的服务器。
所以最终代码Demo这样的:
// httpServer
module.exports = function(app, opts) { return new HttpServer(app, opts);};var HttpServer = function(app, opts) { this.app = app; this.opts = opts; this.confs = {}; var confs = { data: this.onData }; this.server = http.createServer(function(req, res){ var post = ''; req.on('data', function(chunk) { post += chunk; }); req.on('end', function() { post = querystring.parse(post); var cmd = post.cmd; if (!!cmd) { var func = confs[cmd]; if (!!func) { func(post.uid, function(ret){ res.write(JSON.stringify(ret)); res.end(); }); } else { } } }); });};HttpServer.name = '__HttpServer__';HttpServer.prototype.start = function(cb) { this.server.listen(this.opts.port); cb();};HttpServer.prototype.afterStart = function(cb) { cb();};HttpServer.prototype.stop = function(force, cb) { this.server.close(); cb();};HttpServer.prototype.onData = function(uid, cb) { var servers = pomelo.app.getServersByType('area'); var server = dispatcher.dispatch(uid, servers); var sid = server.id; pomelo.app.rpc.area.httpRemote.getUser.toServer(sid, uid, function(res){ cb(res); });};
参考:
https://github.com/NetEase/pomelo/wiki/rpc%E8%B0%83%E7%94%A8%E5%8E%9F%E7%90%86