sdg
Version:
pomelo ts
263 lines • 22.3 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const sdg_1 = tslib_1.__importDefault(require("../sdg"));
const base_1 = tslib_1.__importDefault(require("../base"));
const sioconnector_1 = tslib_1.__importDefault(require("../connectors/sio/sioconnector"));
const events_1 = tslib_1.__importDefault(require("../util/events"));
const defaultEncode = (_route, msg) => msg;
const defaultDecode = (_route, body) => body;
class ConnectorComponent extends base_1.default {
constructor(app, opts) {
super(app, opts);
this.blacklist = [];
this.encode = opts.encode;
this.decode = opts.decode;
this.transformRsp = opts.transformRsp;
this.useHostFilter = opts.useHostFilter;
this.blacklistFun = opts.blacklistFun;
this.forwardMsg = opts.forwardMsg;
this.useDict = !!opts.useDict;
this.useProtobuf = !!opts.useProtobuf;
this.connector = this.getConnector(opts);
this.forwardMsg = opts.forwardMsg;
this.blacklistFun = opts.blacklistFun;
if (opts.useDict) {
app.load(sdg_1.default.components.dictionary, app.get('dictionaryConfig'));
}
if (opts.useProtobuf) {
app.load(sdg_1.default.components.protobuf, app.get('protobufConfig'));
}
}
start() {
this.server = this.app.components.__server__;
this.session = this.app.components.__session__;
this.connection = this.app.components.__connection__;
if (!this.server)
throw 'fail to start connector component for no server component loaded';
if (!this.session)
throw 'fail to start connector component for no session component loaded';
}
afterStart() {
this.connector.start();
this.connector.on('connection', async (socket) => {
const can = await this.hostFilter(socket);
if (can)
this.bindEvents(socket);
});
}
bindEvents(socket) {
if (this.connection) {
const curServer = this.app.getCurServer();
const maxConnections = curServer.maxConn;
const maxLogined = curServer.maxNum;
const statisticInfo = this.connection.getStatisticsInfo();
// 达到最大连接数,t下线
if (maxConnections && statisticInfo.totalConnCount >= maxConnections) {
this.app.logger.warn(`the server has reached the max connections ${maxConnections}`);
socket.disconnect();
return;
}
// 达到最大登录量,t下线
if (maxLogined && statisticInfo.loginedCount >= maxLogined) {
this.app.logger.warn(`the server has reached the max logined count ${maxLogined}`);
socket.disconnect();
return;
}
this.connection.increaseConnectionCount();
}
const session = this.getSession(socket);
let closed = false;
// 绑定session生命周期对应事件
socket.on('error', (err) => {
if (closed)
return;
closed = true;
if (this.connection) {
this.connection.decreaseConnectionCount(session.uid);
}
session.closed(err);
});
socket.on('disconnect', reason => {
if (closed)
return;
closed = true;
this.logger.warn(`[${socket.id}]disconnected: ${reason}`);
if (this.connection) {
this.connection.decreaseConnectionCount(session.uid);
}
session.closed(reason);
});
socket.on('closing', (reason) => {
socket.send({ route: 'onKick', data: { reason }, ts: Date.now() });
});
socket.on('message', async (msg, cb) => {
let msgDecode;
const originRoute = msg.route;
const route = (this.useDict ? this.app.components.__dictionary__.getAbbr()[originRoute] : originRoute) || originRoute;
try {
if (this.decode) {
msgDecode = this.decode(route, msg.body);
}
else if (this.connector.decode && this.useProtobuf) {
msgDecode = this.connector.decode(route, msg.body);
}
else {
msgDecode = defaultDecode(route, msg.body);
}
}
catch (err) {
this.logger.error('decode message error: ', err, msg);
}
const handlerMsg = msgDecode ? Object.assign({ __route__: route }, msgDecode) : { __route__: route };
try {
let data = await this.handleMessage(session, handlerMsg);
if (this.transformRsp) {
data = this.transformRsp(data);
}
if (this.encode) {
data = this.encode(route, data);
}
else if (this.connector.encode && this.useProtobuf) {
data = this.connector.encode(route, data);
}
else {
data = defaultEncode(route, data);
}
cb && cb(null, { route: originRoute, data });
}
catch (err) {
cb && cb(err);
}
});
}
/**
* 处理消息事件
* @param session
* @param msg
* @return {Promise<*>}
*/
async handleMessage(session, msg) {
const type = this.checkServerType(msg.__route__);
if (!type) {
this.logger.warn(`invalid route string. route: ${msg.__route__}`);
return {};
}
// 不转发路由
if (this.forwardMsg === false && type === this.app.getServerType()) {
this.logger.warn(`illegal route. forwardMsg=false route=${msg.__route__}, sessionId=${session.id}`);
// kick client requests for illegal route request.
this.session.kickBySessionId(session.id);
return {};
}
return this.server.globalHandle(msg, session.toFrontendSession());
}
/**
* 获取当前连接的session
* @param socket
* @return {*}
*/
getSession(socket) {
const sid = socket.id;
let session = this.session.get(sid);
if (session)
return session;
const serverId = this.app.getServerId();
session = this.session.create(sid, serverId, socket);
this.logger.debug(`[${serverId}] getSession session is created with session id: ${sid}`);
// bind events for session
session.on('closed', this.onSessionClose.bind(this));
session.on('bind', (uid) => {
this.app.logger.debug(`session: [${session.id}] bind with uid: ${uid}`);
if (this.connection) {
this.connection.addLoginedUser(uid, {
ts: Date.now(),
uid,
ip: socket.ip
});
}
this.app.event.emit(events_1.default.BIND_SESSION, session);
});
session.on('unbind', (uid) => {
if (this.connection) {
this.connection.removeLoginedUser(uid);
}
this.app.event.emit(events_1.default.UNBIND_SESSION, session);
});
return session;
}
send(route, msgRsp, receiveIds, opts) {
let encodeData;
if (this.transformRsp) {
msgRsp = this.transformRsp(msgRsp);
}
if (this.encode) {
encodeData = this.encode(route, msgRsp);
}
else if (this.connector.encode && this.useProtobuf) {
encodeData = this.connector.encode(route, msgRsp);
}
else {
encodeData = defaultEncode(route, msgRsp);
}
if (this.useDict)
route = this.app.components.__dictionary__.getDict()[route] || route;
this.doSend(route, encodeData, receiveIds, opts);
}
async hostFilter(socket) {
if (!this.useHostFilter)
return true;
let check = function (list) {
for (let item of list) {
let exp = new RegExp(item);
if (exp.test(socket.ip)) {
socket.disconnect();
return false;
}
}
return true;
};
// dynamical check
if (this.blacklist.length !== 0 && !check(this.blacklist))
return false;
// static check
if (this.blacklistFun && typeof this.blacklistFun === 'function') {
const list = await this.blacklistFun();
if (!check(list))
return false;
}
return true;
}
doSend(route, data, receiveIds, opts) {
this.app.components.__pushScheduler__.schedule(route, data, receiveIds, opts);
}
getConnector(opts) {
const connector = this.opts.connector;
if (!connector) {
return this.getDefaultConnector(opts.socketOpts);
}
if (typeof connector !== 'function') {
return connector;
}
const curServer = this.app.getCurServer();
return connector(curServer.clientPort, curServer.host, this.opts);
}
getDefaultConnector(socketOpts) {
const curServer = this.app.getCurServer();
return new sioconnector_1.default(curServer.clientPort, curServer.host, socketOpts);
}
checkServerType(route) {
if (!route)
return '';
let idx = route.indexOf('.');
if (idx < 0)
return '';
return route.substring(0, idx);
}
onSessionClose(session) {
// taskManager.closeQueue(session.id, true);
this.app.event.emit(events_1.default.CLOSE_SESSION, session);
}
}
exports.default = ConnectorComponent;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29ubmVjdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbXBvbmVudHMvY29ubmVjdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHlEQUF5QjtBQUd6QiwyREFBMkI7QUFDM0IsMEZBQThEO0FBRzlELG9FQUFvQztBQXNCcEMsTUFBTSxhQUFhLEdBQUcsQ0FBQyxNQUFjLEVBQUUsR0FBWSxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUM7QUFDNUQsTUFBTSxhQUFhLEdBQUcsQ0FBQyxNQUFjLEVBQUUsSUFBYyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUM7QUFFL0QsTUFBcUIsa0JBQW1CLFNBQVEsY0FBSTtJQWdCbEQsWUFBWSxHQUFnQixFQUFFLElBQWdDO1FBQzVELEtBQUssQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFIWixjQUFTLEdBQWEsRUFBRSxDQUFDO1FBSTlCLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUMxQixJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7UUFDMUIsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDO1FBQ3RDLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQztRQUN4QyxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUM7UUFDdEMsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDO1FBQ2xDLElBQUksQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUM7UUFDOUIsSUFBSSxDQUFDLFdBQVcsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQztRQUN0QyxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFekMsSUFBSSxDQUFDLFVB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