pomelo使用採坑記(學習使用部署相關)
阿新 • • 發佈:2019-01-05
pomelo推送方式
pomelo和客戶端保持長連結,推送可以根據頻道推送或者根據使用者連線的伺服器推送
頻道推送
- 建立頻道
let channel = this.app.get('channelService').getChannel(channelName, true);
引數1為頻道的名字,引數2為是否在沒有該頻道的時候建立一個
channel.add(uid, sid);
將使用者放到頻道里面,其中uid為使用者唯一標識,sid為connector的伺服器Id
假設伺服器配置是
"connector":[ {"id":"c1", "host":"172.16.46.14","port":4050, "clientPort": 3050, "frontend": true,"cpu": 1}, {"id":"c2", "host":"172.16.46.14", "port":4051, "clientPort": 3051, "frontend": true,"cpu": 2}, {"id":"c3", "host":"172.16.46.14", "port":4052, "clientPort": 3052, "frontend": true,"cpu": 3}, {"id":"c4", "host":"172.16.46.14", "port":4053, "clientPort": 3053, "frontend": true,"cpu": 4} ]
並且使用者123和connector2連線,使用者234連線connector3
channel.add(123, c2);
channel.add(234, c3);
- 根據頻道推送
呼叫
let channel = this.app.get('channelService').getChannel(channelName);
channel.pushMessage(event, msg, cb);
其中event為客戶端監聽的push方法,例如onAdd
msg為推送引數,隨意傳
cb為推送後的回撥函式
以上方法可以給使用者123和使用者234推送同一條訊息
直接推送
- 儲存使用者Id和使用者connector伺服器的對應關係
let uids = [];
uids.push({uid:123,sid:"c2"});
uids.push({uid:234,sid:"c3"});
- 根據uids推送
this.app.get('channelService').pushMessageByUids(method, params, uids);
其中method為客戶端監聽的push方法,例如onAdd
params為推送引數,隨意傳
bearcat整合
remote和handler整合
- 安裝bearcat
npm install --save bearcat
- app.js中的配置
var bearcat = require('bearcat'); let contextPath = require.resolve('./context.json'); bearcat.createApp([contextPath]); bearcat.start(function() { Configure(); app.set('bearcat', bearcat); // start app app.start(); }); 其中context.json為 { "name": "myApp", "scan": "app", //需要掃描app資料夾下的所有js檔案 "beans": [] }
- 整合到handler
var bearcat = require('bearcat');
var Handler = function (app) {
this.app = app;
this.redis = null; //假設要用到redis
};
var handler = Handler.prototype;
handler.queryEntry = function (msg, session, next) {
//自己的業務邏輯
}
module.exports = function (app) {
return bearcat.getBean({
id: "gateHandler",
func: Handler,
args: [{
name: "app",
value: app
}],
props: [
{name: "redis", ref: "redis"}
]
});
};
其他地方需要使用gateHandler的時候,只需要
var other= function () {
this.gateHandler=null;
}
other.prototype.funA= function(){
this.gateHandler.queryEntry();
...
}
module.exports = {
id: "other",
func: other,
props: [
{name: "gateHandler", ref: "gateHandler"}
]
}
非pomelo框架的service、util等的整合
- 安裝bearcat
npm install --save bearcat
- app.js中的配置
var bearcat = require('bearcat');
let contextPath = require.resolve('./context.json');
bearcat.createApp([contextPath]);
bearcat.start(function() {
Configure();
app.set('bearcat', bearcat);
// start app
app.start();
});
app.configure('development', 'chat', function() { //chat型別的伺服器在development環境下的配置
let chat_OnLineService = bearcat.getBean('chat_OnLineService');
chat_OnLineService.init(app);
});
其中context.json為
{
"name": "myApp",
"scan": "app", //需要掃描app資料夾下的所有js檔案
"beans": []
}
- 整合到chat_OnLineService
檔案onlineService.js中
var OnLineService = function() {};
OnLineService.prototype.init=function (app) {
this.app = app;
}
module.exports = {
id: "chat_OnLineService",
func: OnLineService,
props: []
}
注意onlineService.js必須在app資料夾下,不然掃描不到
其餘使用方式handler、remote和普通js檔案一模一樣
bearcat優勢
- 不需要每次都require,只需要引入bean的id即可,即知道id名字就可以全域性使用
- 類似於spring的javabean的方式,適合習慣了使用java框架開發的開發人員快速上手
預設路由規則採坑
未進行使用者Id繫結的多伺服器遠端呼叫
pomelo進行遠端呼叫時(1、系統遠端呼叫,一般呼叫Handler,例如客戶端呼叫pomelo的online.onLineHandler.showOnlinePlayers方法;2、使用者遠端呼叫,一般呼叫Remote,例如app.rpc.chat.onLineRemote.kick,是由使用者在服務端程式碼中直接呼叫),有個預設路由規則
var uid = session ? (session.uid || '') : '';
var index = Math.abs(crc.crc32(uid.toString())) % list.length;
utils.invokeCallback(cb, null, list[index].id);
即先判斷有無session引數傳入,若有則使用session中繫結好的uid否則用空串,然後進行路由。
當用戶未進行session.bind(uid)之前進行遠端呼叫的時候,如果使用者沒有手動配置路由規則,即使有若干同類型的伺服器,也只會呼叫其中的一臺,負載均衡的效果就沒有了。
所以,如果要在未繫結uid的時候進行多埠或者多伺服器的負載均衡,必須要自定義路由規則而不使用預設規則(在進行auth鑑權伺服器呼叫的時候,往往還不知道使用者的Id)
路由配置
exp.auth = function(session, msg, app, cb) {
let chatServers = app.getServersByType('auth');
if(!chatServers || chatServers.length === 0) {
cb(new Error('can not find cron servers.'));
return;
}
cb(null, chatServers[session.id%chatServers.length].id); //推薦使用session的id或者使用者的裝置資訊等進行路由到不同的伺服器或者埠
};
app.route('auth', routeUtil.auth);
log按照時間日期伺服器分割
按伺服器和天分割
{
"type": "dateFile",
"filename": "${opts:base}/logs/cron-${opts:serverId}.log",
"compress": true,
"pattern": ".yyyy-MM-dd",
"layout": {
"type": "basic"
}
,"backups": 0,
"category":"cron"
}
let logger = require('pomelo-logger').getLogger('cron', __filename);
logger.error("***")
按服務端和小時分割
{
"type": "dateFile",
"filename": "${opts:base}/logs/service-${opts:serverId}.log",
"layout": {
"type": "basic"
},
"pattern": ".yyyy-MM-dd-hh",
"compress": true,
"backups": 0,
"category":"service"
}
let logger = require('pomelo-logger').getLogger('service', __filename);
logger.error("***")
按天分割
{
"type": "dateFile",
"filename": "${opts:base}/logs/error.log",
"compress": true,
"pattern": ".yyyy-MM-dd",
"layout": {
"type": "basic"
}
,"backups": 0,
"category":"error"
}
let logger = require('pomelo-logger').getLogger('error', __filename);
logger.error("***")
IDEA調式
伺服器配置
IDEA配置
步驟
node app.js 或者 pomelo start
- idea裡面直接斷點,搞定
分散式部署
ssh方式
- 假設有2臺機器,A和B
- 在A機器上ssh B的ip(內網和外網ip都可以,如果是內網ip則servers.json裡面就要配置內網ip,否則配置外網ip) ,如果不需要設定密碼則進入步驟4,否則進入步驟3
- 配置機器A和機器B的ssh互信免密登入,網上一搜一大把…
- 在master機器上(假設是A)敲命令
pomelo start -D
- 檢視程序是否全部啟動,A機器敲命令
pomelo list
- 如果沒有全部啟動,則返回步驟3!
非ssh方式
- 假設A機器需要啟動對外7003埠對內4050埠的connector伺服器一臺,B機器需要啟動6053埠的chat伺服器一臺
- 則先在A機器上,使用命令
/usr/local/bin/node /data/node/root/app.js env=dev type=all
/usr/local/bin/node /data/node/root/app.js env=dev id=c1 host=172.*.*.* port=4050 clientPort=7003 frontend=true serverType=connector
- 在B機器上,使用命令
/usr/local/bin/node /data/node/root/app.js env=dev id=ch4 host=172.*.*.* port=6053 serverType=chat
先寫到這吧··有問題聯絡 滕慶亞