init
This commit is contained in:
commit
6ef05cfee1
131
app.js
Normal file
131
app.js
Normal file
@ -0,0 +1,131 @@
|
||||
const express = require('express');
|
||||
const mysql = require("mysql");
|
||||
const utils = require('./utils');
|
||||
const event = require('./event');
|
||||
const config = require('./config');
|
||||
const db = require('./db');
|
||||
|
||||
const app = express();
|
||||
const handlers = {};
|
||||
const middlewares = {};
|
||||
const dbPools = {};
|
||||
let sessionClass = null;
|
||||
let useMiddlewares = [];
|
||||
|
||||
function listen(port) {
|
||||
app.listen(port);
|
||||
}
|
||||
|
||||
function get() {
|
||||
|
||||
}
|
||||
|
||||
function init() {
|
||||
event.emitEvent(event.APP_INITIALIZED_EVENT);
|
||||
}
|
||||
|
||||
function registerHandler(c, a, cb) {
|
||||
handlers[a + '@' + c] = {
|
||||
'cb': cb,
|
||||
'middlewares': useMiddlewares
|
||||
};
|
||||
}
|
||||
|
||||
function injectionSession(sessionCls) {
|
||||
sessionClass = sessionCls;
|
||||
}
|
||||
|
||||
function addMiddleware(name, cb) {
|
||||
middlewares[name] = cb;
|
||||
}
|
||||
|
||||
function useMiddleware(list, cb) {
|
||||
try {
|
||||
useMiddlewares = [];
|
||||
list.forEach((name) => {
|
||||
useMiddlewares.push(middlewares[name]);
|
||||
});
|
||||
cb();
|
||||
} finally {
|
||||
useMiddlewares = [];
|
||||
}
|
||||
}
|
||||
|
||||
function registerDb(name, options) {
|
||||
dbPools[name] = {
|
||||
'options': options,
|
||||
'pool': mysql.createPool({
|
||||
host : options['host'],
|
||||
user : options['user'],
|
||||
password : options['passwd'],
|
||||
database : options['database'],
|
||||
stringifyObjects : true
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
function getDbConn(name) {
|
||||
const ret = {
|
||||
err: null,
|
||||
conn: null,
|
||||
};
|
||||
return new Promise((resolve) => {
|
||||
if (!(name in dbPools)) {
|
||||
ret.err = 'dbname not exists ' + name;
|
||||
resolve(ret);
|
||||
return;
|
||||
}
|
||||
const pool = dbPools[name]['pool'];
|
||||
pool.getConnection(function(err, conn) {
|
||||
ret.err = err;
|
||||
ret.conn = new db(conn);
|
||||
resolve(ret);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
process.on('unhandledRejection', (reason, promise) => {
|
||||
console.log('Unhandled Rejection at:', promise, 'reason:', reason);
|
||||
throw reason;
|
||||
});
|
||||
|
||||
app.get('/webapp/index.php', async (req, rsp) => {
|
||||
const c = req.query.c;
|
||||
const a = req.query.a;
|
||||
const handler = handlers[a + '@' + c];
|
||||
if (handler) {
|
||||
const cb = handler['cb'];
|
||||
const middlewares = handler['middlewares'];
|
||||
if (sessionClass) {
|
||||
const session = new sessionClass(req, rsp);
|
||||
middlewares.forEach(async (m) => {
|
||||
await m(session);
|
||||
});
|
||||
await cb(session);
|
||||
} else {
|
||||
middlewares.forEach(async (m) => {
|
||||
await m(req, rsp);
|
||||
});
|
||||
await cb(req, rsp);
|
||||
}
|
||||
} else {
|
||||
utils.rspErr(rsp, 100, 'not found');
|
||||
}
|
||||
});
|
||||
|
||||
registerHandler('Ops', 'selfChecking', (req, rsp) => {
|
||||
rsp.send(utils.jsonEncode({
|
||||
'errcode': 0,
|
||||
'errmsg': ''
|
||||
}));
|
||||
});
|
||||
|
||||
exports.init = init;
|
||||
exports.listen = listen;
|
||||
exports.get = get;
|
||||
exports.registerHandler = registerHandler;
|
||||
exports.injectionSession = injectionSession;
|
||||
exports.addMiddleware = addMiddleware;
|
||||
exports.useMiddleware = useMiddleware;
|
||||
exports.registerDb = registerDb;
|
||||
exports.getDbConn = getDbConn;
|
1
channel.js
Normal file
1
channel.js
Normal file
@ -0,0 +1 @@
|
||||
exports.SELF_SDK = 6000;
|
18
config.js
Normal file
18
config.js
Normal file
@ -0,0 +1,18 @@
|
||||
const utils = require('./utils');
|
||||
|
||||
let loaded = false;
|
||||
let configJson = null;
|
||||
|
||||
function config(name) {
|
||||
if (!loaded) {
|
||||
let configDir = './config/';
|
||||
if (utils.isOnlineEnv()) {
|
||||
configDir = '../config/';
|
||||
}
|
||||
loaded = true;
|
||||
configJson = utils.readJsonFromFile(configDir + 'config.json');
|
||||
}
|
||||
return configJson ? configJson[name] : null;
|
||||
}
|
||||
|
||||
module.exports = config;
|
155
db.js
Normal file
155
db.js
Normal file
@ -0,0 +1,155 @@
|
||||
const util = require("util");
|
||||
const log = require("./log");
|
||||
|
||||
class DB {
|
||||
|
||||
constructor(conn) {
|
||||
this.conn = conn;
|
||||
}
|
||||
|
||||
execQuery(sql, params) {
|
||||
return new Promise((resolve) => {
|
||||
const ret = {
|
||||
err: null,
|
||||
rows: null,
|
||||
};
|
||||
this.conn.query(sql, params, (err, rows) => {
|
||||
try {
|
||||
if (err) {
|
||||
ret.err = err;
|
||||
resolve(ret);
|
||||
log.error(util.format(
|
||||
'sql:%s err:%s',
|
||||
sql, err
|
||||
));
|
||||
} else {
|
||||
ret.err = err;
|
||||
ret.rows = rows;
|
||||
resolve(ret);
|
||||
}
|
||||
} finally {
|
||||
//this.conn.release();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async execQueryOne(sql, params) {
|
||||
const {err, rows} = await this.execQuery(sql, params);
|
||||
return {
|
||||
'err': err,
|
||||
'row': rows && rows.length > 0 ? rows[0] : null
|
||||
};
|
||||
}
|
||||
|
||||
async execScript(sql, params) {
|
||||
const {err, rows} = await this.execQuery(sql, params);
|
||||
return err;
|
||||
}
|
||||
|
||||
async update(tblName, whereList, fieldList) {
|
||||
const params = [];
|
||||
let sql = 'UPDATE `' + tblName + '` SET ';
|
||||
|
||||
fieldList.forEach((item, index) => {
|
||||
const suffix = (index + 1 < fieldList.length ? ',': '');
|
||||
sql += ' `' + item[0] + '`=?' + suffix;
|
||||
params.push(item[1]);
|
||||
});
|
||||
|
||||
sql += ' WHERE 1=1';
|
||||
whereList.forEach((item, index) => {
|
||||
sql += ' AND ' + item[0] + '=?';
|
||||
params.push(item[1]);
|
||||
});
|
||||
|
||||
this.execScript(sql, params);
|
||||
}
|
||||
|
||||
async insert(tblName, fieldList) {
|
||||
const params = [];
|
||||
let sql = 'INSERT INTO `' + tblName + '` (';
|
||||
|
||||
fieldList.forEach((item, index) => {
|
||||
const suffix = (index + 1 < fieldList.length ? ',': '');
|
||||
sql += '`' + item[0] + '`' + suffix;
|
||||
});
|
||||
|
||||
sql += ') VALUES (';
|
||||
fieldList.forEach((item, index) => {
|
||||
const suffix = (index + 1 < fieldList.length ? ',': '');
|
||||
sql += '?' + suffix;
|
||||
params.push(item[1]);
|
||||
});
|
||||
sql += ')';
|
||||
|
||||
this.execScript(sql, params);
|
||||
}
|
||||
|
||||
async upsert(tblName, whereList, updateList, insertList, opts = null) {
|
||||
const params = [];
|
||||
let sql = 'SELECT * FROM `' + tblName + '` ';
|
||||
{
|
||||
sql += ' WHERE 1=1';
|
||||
whereList.forEach((item, index) => {
|
||||
sql += ' AND ' + item[0] + '=?';
|
||||
params.push(item[1]);
|
||||
});
|
||||
sql += ' LIMIT 1;'
|
||||
}
|
||||
|
||||
const {err, row} = await this.execQueryOne
|
||||
(
|
||||
sql,
|
||||
params
|
||||
);
|
||||
if (err) {
|
||||
return;
|
||||
}
|
||||
if (row) {
|
||||
if (opts && utils.getVal(opts, 'onQueryOk')) {
|
||||
opts['onQueryOk'](row);
|
||||
}
|
||||
await this.update(tblName, whereList, updateList);
|
||||
} else {
|
||||
await this.insert(tblName, insertList);
|
||||
}
|
||||
}
|
||||
|
||||
async _delete(tblName, whereList) {
|
||||
const params = [];
|
||||
let sql = 'DELETE FROM `' + tblName + '` ';
|
||||
|
||||
sql += ' WHERE 1=1';
|
||||
whereList.forEach((item, index) => {
|
||||
sql += ' AND ' + item[0] + '=?';
|
||||
params.push(item[1]);
|
||||
});
|
||||
|
||||
this.execScript(sql, params);
|
||||
}
|
||||
|
||||
async ormSelect(tblName, whereList) {
|
||||
const params = [];
|
||||
let sql = 'SELECT * FROM `' + tblName + '` ';
|
||||
|
||||
sql += ' WHERE 1=1';
|
||||
whereList.forEach((item, index) => {
|
||||
sql += ' AND ' + item[0] + '=?';
|
||||
params.push(item[1]);
|
||||
});
|
||||
|
||||
return this.execQuery(sql, params);
|
||||
}
|
||||
|
||||
async ormSelectOne(tblName, whereList) {
|
||||
const {err, rows} = await this.ormSelect(tblName, whereList);
|
||||
return {
|
||||
'err': err,
|
||||
'row': rows.length > 0 ? rows[0] : null
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = DB;
|
17
event.js
Normal file
17
event.js
Normal file
@ -0,0 +1,17 @@
|
||||
const events = require('events');
|
||||
|
||||
const event = new events.EventEmitter();
|
||||
|
||||
const APP_INITIALIZED_EVENT = '!app.initialized';
|
||||
|
||||
function addListener(eventName, listener) {
|
||||
event.on(eventName, listener);
|
||||
}
|
||||
|
||||
function emitEvent(eventName, ...args) {
|
||||
event.emit(eventName, ...args);
|
||||
}
|
||||
|
||||
exports.addListener = addListener;
|
||||
exports.emitEvent = emitEvent;
|
||||
exports.APP_INITIALIZED_EVENT = APP_INITIALIZED_EVENT;
|
33
log.js
Normal file
33
log.js
Normal file
@ -0,0 +1,33 @@
|
||||
const utils = require('./utils');
|
||||
|
||||
function warning(msg) {
|
||||
internalLog('[WARNING]', msg);
|
||||
}
|
||||
|
||||
function info(msg) {
|
||||
internalLog('[INFO]', msg);
|
||||
}
|
||||
|
||||
function error(msg) {
|
||||
internalLog('[ERROR]', msg);
|
||||
}
|
||||
|
||||
function alert(msg) {
|
||||
internalLog('[ALERT]', msg);
|
||||
}
|
||||
|
||||
function debug(msg) {
|
||||
if (!utils.isOnlineEnv()) {
|
||||
internalLog('[DEBUG]', msg);
|
||||
}
|
||||
}
|
||||
|
||||
function internalLog(logClass, msg) {
|
||||
console.log(utils.formatDate(new Date()) + ' ' + logClass + ' ' + msg);
|
||||
}
|
||||
|
||||
exports.warning = warning;
|
||||
exports.info = info;
|
||||
exports.alert = alert;
|
||||
exports.error = error;
|
||||
exports.debug = debug;
|
1101
package-lock.json
generated
Normal file
1101
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
12
package.json
Normal file
12
package.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "j7",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"private": true,
|
||||
"scripts": {},
|
||||
"dependencies": {
|
||||
"crc-32": "^1.2.1",
|
||||
"express": "^4.17.2",
|
||||
"mysql": "~2.18.1"
|
||||
}
|
||||
}
|
40
sync.js
Normal file
40
sync.js
Normal file
@ -0,0 +1,40 @@
|
||||
const utils = require('./utils');
|
||||
|
||||
class Cond {
|
||||
|
||||
constructor() {
|
||||
this.waitList = [];
|
||||
}
|
||||
|
||||
async wait(timeout) {
|
||||
return new Promise((resolve) => {
|
||||
const waitIdx = this.waitList.length;
|
||||
this.waitList.push({
|
||||
'resolve': resolve,
|
||||
'timer': setTimeout(() => {
|
||||
if (waitIdx < this.waitList.length &&
|
||||
this.waitList[waitIdx]['resolve'] == resolve) {
|
||||
this.waitList = this.waitList.splice(waitIdx, 1);
|
||||
} else {
|
||||
utils.throwError('cond waitIdx error');
|
||||
}
|
||||
resolve();
|
||||
}, timeout)
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
notifyAll() {
|
||||
if (this.waitList.length > 0) {
|
||||
const waitListCopy = this.waitList;
|
||||
this.waitList = [];
|
||||
waitListCopy.forEach((v) => {
|
||||
clearTimeout(v['timer']);
|
||||
v['resolve']();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
exports.Cond = Cond;
|
173
utils.js
Normal file
173
utils.js
Normal file
@ -0,0 +1,173 @@
|
||||
const fs = require('fs');
|
||||
const crypto = require('crypto');
|
||||
const crc32 = require('crc-32');
|
||||
const serverEnv = process.env['SERVER_ENV'];
|
||||
|
||||
function rspErr(rsp, errCode, errMsg) {
|
||||
rsp.send(jsonEncode({
|
||||
'errcode': errCode,
|
||||
'errmsg': errMsg
|
||||
}));
|
||||
}
|
||||
|
||||
function rspOk(rsp) {
|
||||
rsp.send(jsonEncode({
|
||||
'errcode': 0,
|
||||
'errmsg': ''
|
||||
}));
|
||||
}
|
||||
|
||||
function rspData(rsp, data) {
|
||||
data['errcode'] = 0;
|
||||
data['errmsg'] = '';
|
||||
rsp.send(jsonEncode(data));
|
||||
}
|
||||
|
||||
function readJsonFromFile(url) {
|
||||
const jsondata = fs.readFileSync(url, "utf8");
|
||||
const json = JSON.parse(jsondata);
|
||||
return json;
|
||||
}
|
||||
|
||||
async function sleep(timeout) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
setTimeout(function () {
|
||||
resolve();
|
||||
}, timeout);
|
||||
});
|
||||
}
|
||||
|
||||
function emptyReplace(val, newVal) {
|
||||
return !val ? newVal : val;
|
||||
}
|
||||
|
||||
function throwError(msg) {
|
||||
console.log(msg);
|
||||
throw msg;
|
||||
}
|
||||
|
||||
function isOnlineEnv() {
|
||||
return !serverEnv;
|
||||
}
|
||||
|
||||
function getUtcTime() {
|
||||
return Math.floor((new Date()).getTime() / 1000);
|
||||
}
|
||||
|
||||
function formatDate(date) {
|
||||
const year = date.getFullYear();
|
||||
const month = date.getMonth() + 1;//月份是从0开始的
|
||||
const day = date.getDate();
|
||||
const hour = date.getHours();
|
||||
const min = date.getMinutes();
|
||||
const sec = date.getSeconds();
|
||||
return year + '-' +
|
||||
(month < 10 ? '0' + month : month) + '-' +
|
||||
(day < 10 ? '0' + day : day) + ' ' +
|
||||
(hour < 10 ? '0' + hour : hour) + ':' +
|
||||
(min < 10 ? '0' + min : min) + ':' +
|
||||
(sec < 10 ? '0' + sec : sec);
|
||||
}
|
||||
|
||||
function pad(num, n) {
|
||||
let result = num.toString();
|
||||
let len = result.length;
|
||||
while (len < n) {
|
||||
result = '0' + result;
|
||||
len++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function randRange(min, max) {
|
||||
if (min >= max) {
|
||||
return min;
|
||||
}
|
||||
return min + Math.random() * max;
|
||||
}
|
||||
|
||||
function jsonEncode(obj) {
|
||||
return JSON.stringify(obj);
|
||||
}
|
||||
|
||||
function isArray(val) {
|
||||
return Array.isArray(val);
|
||||
}
|
||||
|
||||
function isObject(val) {
|
||||
return typeof(obj) == "object";
|
||||
}
|
||||
|
||||
function crc32Str(str) {
|
||||
return crc32.str('' + str);
|
||||
}
|
||||
|
||||
function createAccountId(channel, gameId, openId) {
|
||||
const accountId = `${channel}_${gameId}_${openId}`;
|
||||
return accountId;
|
||||
}
|
||||
|
||||
function extractChannel(accountId) {
|
||||
const ss = accountId.split('_');
|
||||
return ss[0];
|
||||
}
|
||||
|
||||
function extractGameId(accountId) {
|
||||
const ss = accountId.split('_');
|
||||
return ss[1];
|
||||
}
|
||||
|
||||
function extractOpenId(accountId) {
|
||||
const channel = extractChannel(accountId);
|
||||
const gameId = extractGameId(accountId);
|
||||
const openId = accountId.substr(accountId.indexOf(`${channel}_${gameId}_`));
|
||||
return openId;
|
||||
}
|
||||
|
||||
function createSessionId(accountId, registerTime, secretKey) {
|
||||
const nowTime = getUtcTime();
|
||||
const rand = randRange(1, 1000000000);
|
||||
const sessionId = '' +
|
||||
nowTime + '_' +
|
||||
registerTime + '_' +
|
||||
rand + '_' +
|
||||
md5Str('' + accountId + secretKey + registerTime + nowTime);
|
||||
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
function md5Str(data) {
|
||||
const hash = crypto.createHash('md5');
|
||||
return hash.update(data).digest('hex');
|
||||
}
|
||||
|
||||
function getVal(obj, key, defVal = null) {
|
||||
if (!obj){
|
||||
return val;
|
||||
}
|
||||
return key in obj ? obj[key] : defVal;
|
||||
}
|
||||
|
||||
exports.rspErr = rspErr;
|
||||
exports.rspOk = rspOk;
|
||||
exports.rspData = rspData;
|
||||
exports.readJsonFromFile = readJsonFromFile;
|
||||
exports.sleep = sleep;
|
||||
exports.emptyReplace = emptyReplace;
|
||||
exports.throwError = throwError;
|
||||
exports.isOnlineEnv = isOnlineEnv;
|
||||
exports.getUtcTime = getUtcTime;
|
||||
exports.formatDate = formatDate;
|
||||
exports.pad = pad;
|
||||
exports.randRange = randRange;
|
||||
exports.jsonEncode = jsonEncode;
|
||||
exports.isArray = isArray;
|
||||
exports.isObject = isObject;
|
||||
exports.crc32Str = crc32Str;
|
||||
exports.createAccountId = createAccountId;
|
||||
exports.extractChannel = extractChannel;
|
||||
exports.extractGameId = extractGameId;
|
||||
exports.extractOpenId = extractOpenId;
|
||||
exports.createSessionId = createSessionId;
|
||||
exports.md5Str = md5Str;
|
||||
exports.getVal = getVal;
|
Loading…
x
Reference in New Issue
Block a user