import * as mysql from "mysql"; import { Z_FIXED } from "zlib"; import GameConf from "./conf/GameConf"; import SKDataUtil from "./game/gear/SKDataUtil"; import SKLogger from "./game/gear/SKLogger"; import SnowFlack from "./game/gear/SnowFlake"; import SnowFlack53 from "./game/gear/SnowFlake53"; import DB from "./game/utils/DB"; let socketio = require('socket.io'); // 未知异常捕获 process.on('uncaughtException', (error: Error) => { SKLogger.warn(`$异常:${error.message}\n${error.stack}`); }); // 数据库连接 class DBAgent { socket: any; name: string; id: number; constructor(socket: any) { this.socket = socket; this.name = ''; this.id = 0; } send(event: string, data: any) { if (!this.socket.connected) { SKLogger.warn(`数据库连接:[${this.id}:${this.name}]已经断开连接,取消发送[${event}]`); return; } this.socket.emit(event, data); } } // 数据库服务器 export default class DBServ { static shared = new DBServ(); agent: DBAgent; pool: mysql.Pool; agent_seed_id: number = 0; socket_pool: any = {}; constructor() { SKLogger.initLog("dbserv"); SKLogger.info('系统配置表加载完毕'); this.init(); } init() { this.pool = mysql.createPool({ host: GameConf.db_ip, user: GameConf.db_user, password: GameConf.db_pwd, database: GameConf.db_name, port: GameConf.db_port, connectionLimit: 300, connectTimeout: 60 * 60 * 1000, acquireTimeout: 60 * 60 * 1000, timeout: 60 * 60 * 1000, multipleStatements: true, charset: "utf8mb4" }); SKLogger.info('数据库连接:初始化完毕!'); } // 重置连接 reset(socket: any) { let agent = new DBAgent(socket); let self = this; socket.on('sql', (data: any) => { self.fsql(agent, data); }); socket.on('reg', (data: any) => { self.freg(agent, data); }); socket.on('close', (data: any) => { self.fclose(agent); }); socket.on("connect_error", (data: any) => { SKLogger.warn(`数据库连接:[${agent.id}:${agent.name}]连接错误[${data}]`); }); socket.on("connect_timeout", (data: any) => { SKLogger.warn(`数据库连接:[${agent.id}:${agent.name}]连接超时[${data}]`); }); socket.on("error", (data: any) => { SKLogger.warn(`数据库连接:[${agent.id}:${agent.name}]错误[${data}]`); }); socket.on("disconnect", (reason: string) => { SKLogger.warn(`数据库连接:[${agent.id}:${agent.name}]断开连接[${reason}]`); self.fclose(agent); }); socket.on("reconnect", (data: any) => { SKLogger.warn(`数据库连接:[${agent.id}:${agent.name}]重连[${data}]`); }); socket.on("reconnect_attempt", (data: any) => { SKLogger.info("尝试重新连接"); }); socket.on("reconnect_error", (data: any) => { SKLogger.warn(`数据库连接:[${agent.id}:${agent.name}]重连错误[${data}]`); }); socket.on("reconnect_failed", (data: any) => { SKLogger.warn(`数据库连接:[${agent.id}:${agent.name}]连接失败[${data}]`); }); socket.on("ping", (data: any) => { SKLogger.info(`数据库连接:[${agent.id}:${agent.name}]PING[${data}]`); }); socket.on("pong", (data: any) => { SKLogger.info(`数据库连接:[${agent.id}:${agent.name}]PONG[${data}]`); }); agent.id = this.agent_seed_id; this.socket_pool[this.agent_seed_id] = agent; this.agent_seed_id++; SKLogger.info(`数据库连接:[${agent.id}]已连接!`); } lanuch() { let self = this; let io = socketio(GameConf.gate_db_port, { "transports": [ 'websocket', 'polling' ] }); io.sockets.on('connection', (socket: any) => { if(socket.handshake.address != "::ffff:127.0.0.1"){ return socket.close() } self.reset(socket); }); SKLogger.info(`数据库服务V${GameConf.version}启动完毕,正在监听本地:${GameConf.gate_db_port}`); } fsql(agent: DBAgent, data: any) { this.query(data.sql, (error: any, rows: any) => { if (error) { let info = DB.errorInfo(error); SKLogger.warn(`SQL错误:[${data.sql}][${info}]`); agent.send('sqled', { id: data.id, error: error, rows: null, }); return; } agent.send('sqled', { id: data.id, error: null, rows: rows, }); }); } // 注册连接 freg(agent: DBAgent, data: any) { agent.name = data.name; SKLogger.info(`数据库连接:[${agent.id}:${agent.name}]完成注册`); } // 关闭连接 fclose(agent: DBAgent) { let temp: DBAgent = SKDataUtil.valueForKey(this.socket_pool, agent.id); if (temp == null) { return; } SKLogger.info(`数据库连接:[${temp.id}:${temp.name}]关闭`); delete this.socket_pool[temp.id]; } // 执行查询 query(sql: string, callback: (error: Error, rows: any) => void) { if (SKDataUtil.isEmptyString(sql)) { SKLogger.warn(`SQL错误:SQL不能为空!`); return; } this.pool.getConnection((conn_error: mysql.MysqlError, conn: mysql.PoolConnection) => { if (conn_error) { SKLogger.warn(`SQL连接错误:${conn_error}\n[${sql}]`); callback(conn_error, null); } else { conn.query(sql, (query_error: Error, rows: any, fields: any) => { if (query_error) { SKLogger.warn(`SQL查询错误:${query_error}\n[${sql}]`); } //释放连接 conn.release(); //事件驱动回调 callback(query_error, rows); }); } }); }; } new DBServ().lanuch();