feat: node code perf

This commit is contained in:
https://blog.iamtsm.cn
2023-04-21 22:32:23 +08:00
parent 5985dbe078
commit 491b05f7a8
56 changed files with 3461 additions and 2865 deletions

View File

@@ -37,11 +37,7 @@
"router": {
"filter": {
"whiteDir": [
"socket",
"tables",
"worker",
"oss",
"openai"
],
"whiteFile": [
"router.js"

View File

@@ -1,20 +1,47 @@
const express = require("express"); //express
const conf = require("./conf/cfg"); //conf
const fileApiRouters = require("./src/router")(conf); //file routers
const express = require("express");
const conf = require("./conf/cfg.json");
const fileApiRouters = require("./src/controller/router")();
let resRouter = conf.router.res;
const db = require("./src/tables/db"); //db
let app = express();
console.log("resource including...")
console.log("api init start ...")
//res
for(let key in resRouter) app.use(key,express.static(resRouter[key]));
for (let key in resRouter) {
app.use(key, express.static(resRouter[key]));
}
//file api
for(let key in fileApiRouters) app.use(key,fileApiRouters[key])
for (let key in fileApiRouters) {
app.use(key, fileApiRouters[key])
}
if (!conf.db.open) {// 没开db
app.listen(conf.node.port);
console.log("express init...")
app.use(async function (req, res, next) {
req.ctx = {};
req.ctx.tables = {};
req.ctx.dbClient = {};
await next();
})
app.listen(conf.node.port);
console.log("express init done ...")
console.log("web server runing on ", conf.node.port, " successful");
} else { // 开了db
(async () => {
let { tables, dbClient } = await db.excute(conf)
console.log("db init done ...")
app.use(async function (req, res, next) {
req.ctx = {};
req.ctx.tables = tables;
req.ctx.dbClient = dbClient;
await next();
})
console.log("server runing on ",conf.node.port," successful");
app.listen(conf.node.port);
console.log("express init done ...")
console.log("web server runing on ", conf.node.port, " successful");
})();
}

View File

@@ -1,45 +1,25 @@
const http = require('http'); // http
const socketIO = require('socket.io'); //socket
const app = require("express")(); //express
const db = require("./src/tables/db"); //db
const conf = require("./conf/cfg.json"); //conf
const utils = require("./utils/utils"); //utils
const socket = require("./src/socket/index") //socket handler
let tables = {};
let sql = {};
// Socket连接监听
let io = socketIO.listen(http.createServer().listen(conf.ws.port));
if(conf.db.open){
// db init
let dbData = db.excute(conf);
tables = dbData.tables;
sql = dbData.sql;
if (!conf.db.open) {// 没开db
app.use(async function (req,res,next) {
req.ctx = {};
req.ctx.tables = tables;
req.ctx.sql = sql;
req.ctx.Sql = Sql;
await next();
})
console.log("db init...")
console.log("db not open ...")
socket.excute({}, {}, io);
console.log("socket init done ...")
console.log("socket server listen on ", conf.ws.port, " successful");
} else { // 开了db
(async () => {
let { tables, dbClient } = await db.excute(conf)
console.log("db init done ...")
socket.excute(tables, dbClient, io);
console.log("socket init done ...")
console.log("socket server listen on ", conf.ws.port, " successful");
})();
}
//log flow init --日志流水初始
app.use(async function (req,res,next) {
res.tl = {};
res.tl.flowId = utils.genFlow();
await next();
})
console.log("flow init...")
//Socket连接监听
let io = socketIO.listen(
http.createServer().listen(conf.ws.port)
);
conf.ws.io = io;
socket.excute(tables, sql, conf);
console.log("socket init...")
console.log("socket listen on ",conf.ws.port," successful");

View File

@@ -1662,7 +1662,12 @@ axios.get(window.prefix + "/api/comm/initData", {}).then((initData) => {
return;
}
this.setNickName();
this.socket.emit('createAndJoin', { room: this.roomId, nickName : this.nickName });
this.socket.emit('createAndJoin', {
room: this.roomId,
type : 'password',
password : '',
nickName : this.nickName
});
this.isJoined = true;
this.addPopup({
title : "文件房间",
@@ -1694,7 +1699,11 @@ axios.get(window.prefix + "/api/comm/initData", {}).then((initData) => {
return;
}
this.setNickName();
this.socket.emit('createAndJoin', { room: this.roomId, type: type, nickName : this.nickName });
this.socket.emit('createAndJoin', {
room: this.roomId,
type: type,
nickName : this.nickName
});
this.isJoined = true;
this.addPopup({
title : "流媒体房间",
@@ -1735,7 +1744,12 @@ axios.get(window.prefix + "/api/comm/initData", {}).then((initData) => {
return;
}
this.setNickName();
this.socket.emit('createAndJoin', { room: this.roomId, password: password, nickName : this.nickName });
this.socket.emit('createAndJoin', {
room: this.roomId,
type : 'password',
password: password,
nickName : this.nickName
});
this.isJoined = true;
this.addPopup({
title : "密码房间",

View File

@@ -1,12 +1,13 @@
const express = require("express"); //express
const conf = require("./conf/cfg"); //conf
const fileApiRouters = require("./src/router")(conf); //file routers
const express = require("express");
const fs = require('fs');
const https = require('https');
const conf = require("./conf/cfg.json");
const fileApiRouters = require("./src/controller/router")();
let resRouter = conf.router.res;
const fs = require('fs'); // fs
const https = require('https'); // http
const db = require("./src/tables/db");
let app = express();
console.log("resource including...")
console.log("api init start ...")
//res
for(let key in resRouter) app.use(key,express.static(resRouter[key]));
@@ -14,12 +15,43 @@ for(let key in resRouter) app.use(key,express.static(resRouter[key]));
//file api
for(let key in fileApiRouters) app.use(key,fileApiRouters[key])
let options = {
if (!conf.db.open) {// 没开db
app.use(async function (req, res, next) {
req.ctx = {};
req.ctx.tables = {};
req.ctx.dbClient = {};
await next();
})
let options = {
key: fs.readFileSync('./conf/keys/server.key'),
cert: fs.readFileSync('./conf/keys/server.crt')
}
https.createServer(options,app).listen(conf.node.port);
console.log("express init done ...")
console.log("web server runing on ", conf.node.port, " successful");
} else {// 开了db
(async () => {
let { tables, dbClient } = await db.excute(conf)
console.log("db init done ...")
app.use(async function (req, res, next) {
req.ctx = {};
req.ctx.tables = tables;
req.ctx.dbClient = dbClient;
await next();
})
let options = {
key: fs.readFileSync('./conf/keys/server.key'),
cert: fs.readFileSync('./conf/keys/server.crt')
}
https.createServer(options,app).listen(conf.node.port);
console.log("express init done ...")
console.log("web server runing on ", conf.node.port, " successful");
})();
}
https.createServer(options,app).listen(conf.node.port);
console.log("express init...")
console.log("server runing on ",conf.node.port," successful");
console.log("web server runing on ",conf.node.port," successful");

View File

@@ -1,38 +1,9 @@
const https = require('https'); // http
const socketIO = require('socket.io'); //socket
const app = require("express")(); //express
const fs = require('fs'); // fs
const db = require("./src/tables/db"); //db
const conf = require("./conf/cfg.json"); //conf
const utils = require("./utils/utils"); //utils
const socket = require("./src/socket/index") //socket handler
let tables = {};
let sql = {};
if(conf.db.open){
// db init
let dbData = db.excute(conf);
tables = dbData.tables;
sql = dbData.sql;
app.use(async function (req,res,next) {
req.ctx = {};
req.ctx.tables = tables;
req.ctx.sql = sql;
req.ctx.Sql = Sql;
await next();
})
console.log("db init...")
}
//log flow init --日志流水初始
app.use(async function (req,res,next) {
res.tl = {};
res.tl.flowId = utils.genFlow();
await next();
})
console.log("flow init...")
const https = require('https');
const socketIO = require('socket.io');
const fs = require('fs');
const db = require("./src/tables/db");
const conf = require("./conf/cfg.json");
const socket = require("./src/socket/index")
//Socket连接监听
let options = {
@@ -42,9 +13,21 @@ let options = {
let io = socketIO.listen(
https.createServer(options).listen(conf.ws.ssl_port)
);
conf.ws.io = io;
socket.excute(tables, sql, conf);
console.log("socket init...")
if (!conf.db.open) {// 没开db
console.log("socket listen on ",conf.ws.ssl_port," successful");
console.log("db not open ...")
socket.excute({}, {}, io);
console.log("socket init done ...")
console.log("socket server listen on ", conf.ws.port, " successful");
} else {// 开了db
(async () => {
let { tables, dbClient } = await db.excute(conf)
console.log("db init done ...")
socket.excute(tables, dbClient, io);
console.log("socket init done ...")
console.log("socket server listen on ", conf.ws.port, " successful");
})();
}

67
src/bussiness/dog/dog.js Normal file
View File

@@ -0,0 +1,67 @@
const dog = require("./../../dao/dog/dog");
/**
* 操作记录
* @param {*} data
*/
async function dogData(data) {
let req = {
ctx: {
tables: data.tables
},
params: data
};
let res = 0;
try {
res = await dog.addDogData(req, null);
} catch (e) {
console.log(e)
}
return res && res.dataValues ? res.dataValues.id : 0
}
/**
* 获取最近10条公共聊天室数据
* @param {*} data
*/
async function getDogChating10Info(data) {
let req = {
ctx: {
tables: data.tables,
dbClient: data.dbClient
}
};
return await dog.getDogChating10Info(req, null);
}
/**
* 获取操作数据信息
* @param {*} data
* @returns
*/
async function getDogManageInfo(data){
let req = {
ctx: {
tables: data.tables,
dbClient: data.dbClient,
sockets: data.sockets
},
params: {
limit: 10,
day: data.day,
}
}
return await dog.getDogManageInfo(req, null);
}
module.exports = {
dogData,
getDogChating10Info,
getDogManageInfo
}

View File

@@ -0,0 +1,225 @@
const bussinessDog = require("./../../bussiness/dog/dog")
const cfg = require("../../../conf/cfg.json");
const dbOpen = cfg.db.open
/**
* 获取数据传输页面
* @param {*} data
* @returns
*/
async function getDataPageHtml(data) {
if (!dbOpen) {
return 'db配置未开启';
}
let resData = await bussinessDog.getDogManageInfo({
tables: data.tables,
dbClient: data.dbClient,
sockets: data.sockets,
day: data.day,
})
return `
<style>
.layui-layer{
transition: all 0.5s cubic-bezier(0.18, 0.89, 0.32, 1.28) 0s;
}
.layui-layer-page .layui-layer-content {
background: #ededed;
}
.layuiadmin-span-color, .layuiadmin-big-font{
font-weight: bold;
}
.layui-table{
word-break: break-all;box-shadow: 10px 3px 15px 3px rgb(0 0 0 / 5%);
}
.room-recent-title{
margin-left: 10px;margin-top: 10px;font-weight: bold;font-size: 17px;
}
.room-status-svg{
width: 15px; height: 15px; top: 2px; position: relative;
}
.layui-layer .layui-layer-page .layui-layer-tab{
box-sizing: content-box;
}
.layui-layer-tab .layui-layer-title span {
min-width: unset;
max-width: unset;
}
.layui-layer-tab .layui-layer-title {
display: inline-flex;
width: 100%;
padding: 0;
}
</style>
<link rel="stylesheet" href="static/layui/css/admin.css" media="all">
<div class="layui-fluid" id="manageFile" v-cloak>
<span style="position: absolute; top: 22px; font-size: 20px; color: cadetblue; font-weight: 900; margin-left: 15px;"> 当前查询时间: </span>
<input type="text" class="layui-input" value="${data.day}" id="dayFile" style="padding-right: 12px;text-align: right;margin-bottom: 10px; font-size: 20px; color: cadetblue; font-weight: 900;margin-bottom: 10px;" onclick="reRenderDateFile()">
<div class="layui-row layui-col-space15" id="tl_console_data_tpl_view">
<div class="layui-col-sm6 layui-col-md3">
<div class="layui-card">
<div class="layui-card-header">
{{chooseDay}}文件传输 <span class="layui-badge layui-bg-blue layuiadmin-badge">天</span>
</div>
<div class="layui-card-body layuiadmin-card-list">
<p class="layuiadmin-big-font">{{transferFileToday}}次</p>
<p> 总计文件传输
<span class="layuiadmin-span-color">{{transferFileAll}}次
<i class="layui-inline layui-icon layui-icon-home"></i>
</span>
</p>
</div>
</div>
</div>
<div class="layui-col-sm6 layui-col-md3">
<div class="layui-card">
<div class="layui-card-header">
{{chooseDay}}文件传输大小
<span class="layui-badge layui-bg-cyan layuiadmin-badge">天</span>
</div>
<div class="layui-card-body layuiadmin-card-list">
<p class="layuiadmin-big-font">{{transferFileSizeTodady}}M</p>
<p>
总计文件传输大小
<span class="layuiadmin-span-color">暂不统计
<i class="layui-inline layui-icon layui-icon-user"></i></span>
</p>
</div>
</div>
</div>
<div class="layui-col-sm6 layui-col-md3">
<div class="layui-card">
<div class="layui-card-header">
{{chooseDay}}文本传输
<span class="layui-badge layui-bg-green layuiadmin-badge">天</span>
</div>
<div class="layui-card-body layuiadmin-card-list">
<p class="layuiadmin-big-font">{{transferTxtTodady}}次</p>
<p>
总计文本传输
<span class="layuiadmin-span-color"> {{transferTxtAll}}次
<i class="layui-inline layui-icon layui-icon-top" style="font-size: 25px;"></i></span>
</p>
</div>
</div>
</div>
<div class="layui-col-sm6 layui-col-md3">
<div class="layui-card">
<div class="layui-card-header">
{{chooseDay}}公共频道发言
<span class="layui-badge layui-bg-orange layuiadmin-badge">天</span>
</div>
<div class="layui-card-body layuiadmin-card-list">
<p class="layuiadmin-big-font">{{transferCommTxtToday}}次</p>
<p>
总计公共频道发言
<span class="layuiadmin-span-color">{{transferCommTxtAll}}次
<i class="layui-inline layui-icon layui-icon-top" style="font-size: 25px;"></i></span>
</p>
</div>
</div>
</div>
<div class="layui-col-sm12">
<div class="layui-row layui-col-space15">
<div class="layui-col-sm12">
<div class="room-recent-title">{{chooseDay}}文件传输列表</div>
<table class="layui-table">
<thead> <tr> <th>房间频道</th> <th>文件名称</th> <th>文件大小</th> <th>发送时间</th> </tr> </thead>
<tbody>
<tr v-for="file in fileList">
<td>{{file.room}}</td>
<td><pre>{{file.name}}</pre></td>
<td>{{file.size}}M</td>
<td>{{file.createTime}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="layui-col-sm12">
<div class="layui-row layui-col-space15">
<div class="layui-col-sm12">
<div class="room-recent-title">{{chooseDay}}文本传输列表</div>
<table class="layui-table">
<thead> <tr> <th>房间频道</th> <th>文本内容</th> <th>文本长度</th> <th>发送时间</th> </tr> </thead>
<tbody>
<tr v-for="txt in txtList">
<td>{{txt.room}}</td>
<td><pre>{{txt.content}}</pre></td>
<td>{{txt.size}}字符</td>
<td>{{txt.createTime}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="layui-col-sm12">
<div class="layui-row layui-col-space15">
<div class="layui-col-sm12">
<div class="room-recent-title">{{chooseDay}}公共频道发言</div>
<table class="layui-table">
<thead> <tr> <th>房间频道</th> <th>文本内容</th> <th>文本长度</th> <th>发送时间</th> </tr> </thead>
<tbody>
<tr v-for="txt in commTxtList">
<td>{{txt.room}}</td>
<td><pre>{{txt.content}}</pre></td>
<td>{{txt.size}}字符</td>
<td>{{txt.createTime}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<script>
window.reRenderDateFile = function(){
layui.laydate.render({
elem: '#dayFile',
closeStop: '#dayFile',
trigger: 'click',
max : '${new Date()}',
done: function(value, date, endDate){
if(value){
window.manageReload({
time : value
})
}
}
});
}
layui.use(['laydate'], function () {
window.reRenderDateFile()
});
new Vue({
el: '#manageFile',
data: function () {
return ${JSON.stringify(resData)}
},
methods: {
sortList : function(list, fields){
return list.sort(function(a, b){return a[fields].localeCompare(b[fields],'zh-CN')})
}
},
mounted: function () {
}
})
</script>
`
}
module.exports = {
getDataPageHtml,
}

View File

@@ -0,0 +1,194 @@
const bussinessRoom = require("./../../bussiness/room/room")
const cfg = require("../../../conf/cfg.json");
const dbOpen = cfg.db.open
/**
* 获取房间页面
* @param {*} data
* @returns
*/
async function getRoomPageHtml(data) {
if (!dbOpen) {
return 'db配置未开启';
}
let resData = await bussinessRoom.getRoomHistoryInfo({
tables: data.tables,
dbClient: data.dbClient,
sockets: data.sockets,
day: data.day,
})
return `
<style>
.layui-layer{
box-sizing: content-box;
transition: all 0.5s cubic-bezier(0.18, 0.89, 0.32, 1.28) 0s;
}
.layui-layer-page .layui-layer-content {
background: #ededed;
}
.layuiadmin-span-color, .layuiadmin-big-font{
font-weight: bold;
}
.layui-table{
word-break: break-all;box-shadow: 10px 3px 15px 3px rgb(0 0 0 / 5%);
}
.room-recent-title{
margin-left: 10px;margin-top: 10px;font-weight: bold;font-size: 17px;
}
.room-status-svg{
width: 15px; height: 15px; top: 2px; position: relative;
}
.layui-layer-tab .layui-layer-title span {
min-width: unset;
max-width: unset;
}
.layui-layer-tab .layui-layer-title {
display: inline-flex;
width: 100%;
padding: 0;
}
</style>
<link rel="stylesheet" href="static/layui/css/admin.css" media="all">
<div class="layui-fluid" id="manageRoom" v-cloak>
<span style="position: absolute; top: 22px; font-size: 20px; color: cadetblue; font-weight: 900; margin-left: 15px;"> 当前查询时间: </span>
<input type="text" value="${data.day}" class="layui-input" id="dayRoom" style="padding-right: 12px;text-align: right;margin-bottom: 10px; font-size: 20px; color: cadetblue; font-weight: 900;margin-bottom: 10px;" onclick="reRenderDateRoom()">
<div class="layui-row layui-col-space15" id="tl_console_home_tpl_view">
<div class="layui-col-sm6 layui-col-md3">
<div class="layui-card">
<div class="layui-card-header">
{{chooseDay}}房间频道创建/加入 <span class="layui-badge layui-bg-blue layuiadmin-badge">天</span>
</div>
<div class="layui-card-body layuiadmin-card-list">
<p class="layuiadmin-big-font">{{createRoomToday}}个</p>
<p> 总计房间频道创建/加入
<span class="layuiadmin-span-color">{{createRoomAll}}个
<i class="layui-inline layui-icon layui-icon-home"></i>
</span>
</p>
</div>
</div>
</div>
<div class="layui-col-sm6 layui-col-md3">
<div class="layui-card">
<div class="layui-card-header">
{{chooseDay}}加入房间人数
<span class="layui-badge layui-bg-cyan layuiadmin-badge">天</span>
</div>
<div class="layui-card-body layuiadmin-card-list">
<p class="layuiadmin-big-font">{{joinRoomTodady}}人</p>
<p>
总计加入房间人数
<span class="layuiadmin-span-color">{{joinRoomAll}}人
<i class="layui-inline layui-icon layui-icon-user"></i></span>
</p>
</div>
</div>
</div>
<div class="layui-col-sm12">
<div class="layui-row layui-col-space15">
<div class="layui-col-sm12">
<div class="room-recent-title">在线房间列表</div>
<table class="layui-table">
<thead> <tr> <th>房间频道</th> <th>在线状态</th> <th>房间人数</th> <th>创建时间</th> </tr> </thead>
<tbody>
<tr v-for="r in onlineRoomList">
<td style="font-weight: bold;">{{r.room}}</td>
<td style="font-weight: bold;">
<svg class="room-status-svg" viewBox="0 0 1024 1024" p-id="4241" width="128" height="128">
<path d="M512 277.333333a234.666667 234.666667 0 1 0 0 469.333334 234.666667 234.666667 0 0 0 0-469.333334z" p-id="4242" fill="#1afa29"></path>
</svg>
{{r.status}}
</td>
<td style="font-weight: bold;">{{r.userNumber}}</td>
<td>{{r.createTime}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="layui-col-sm12">
<div class="layui-row layui-col-space15">
<div class="layui-col-sm12">
<div class="room-recent-title">{{chooseDay}}房间统计</div>
<table class="layui-table">
<thead> <tr> <th>房间频道</th> <th>聚合创建次数</th> <th>最近创建时间</th> </tr> </thead>
<tbody>
<tr v-for="r in todayRoomList">
<td style="font-weight: bold;">{{r.room}}</td>
<td style="font-weight: bold;">{{r.count}}</td>
<td>{{r.createTime}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="layui-col-sm12">
<div class="layui-row layui-col-space15">
<div class="layui-col-sm12">
<div class="room-recent-title">{{chooseDay}}访问设备/IP</div>
<table class="layui-table">
<thead> <tr> <th>房间频道</th> <th>IP地址</th> <th>设备信息</th> <th>时间</th> </tr> </thead>
<tbody>
<tr v-for="userAgentIp in userAgentIpList">
<td style="font-weight: bold;">{{userAgentIp.room}}</td>
<td >{{userAgentIp.Ip}}</td>
<td>{{userAgentIp.userAgent}}</td>
<td>{{userAgentIp.createTime}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<script>
window.reRenderDateRoom = function(){
layui.laydate.render({
elem: '#dayRoom',
closeStop: '#dayRoom',
trigger: 'click',
max : '${new Date()}',
done: function(value, date, endDate){
if(value){
window.manageReload({
time : value
})
}
}
});
}
layui.use(['laydate'], function () {
window.reRenderDateRoom()
});
new Vue({
el: '#manageRoom',
data: function () {
return ${JSON.stringify(resData)}
},
methods: {
sortList : function(list, fields){
return list.sort(function(a, b){return a[fields].localeCompare(b[fields],'zh-CN')})
}
},
mounted: function () {
}
})
</script>
`
}
module.exports = {
getRoomPageHtml
}

View File

@@ -0,0 +1,262 @@
const bussinessRoom = require("./../../bussiness/room/room")
const cfg = require("../../../conf/cfg.json");
const dbOpen = cfg.db.open
/**
* 获取设置房间页面
* @param {*} data
* @returns
*/
async function getSettingPageHtml(data) {
if (!dbOpen) {
return 'db配置未开启';
}
let resData = await bussinessRoom.getOrCreateManageRoom({
tables: data.tables,
rname: data.room,
sid: data.socketId,
ip: data.ip,
device: data.userAgent,
content: JSON.stringify({
openSendBug: true,
openScreen: true,
openOnlineUser: true,
openShareRoom: true,
openAiChat: true,
openGetCodeFile: true,
openVideoShare: true,
openPasswordRoom: true,
openScreenShare: true,
openFileTransfer: true,
openTxtTransfer: true,
openTurnServer: true,
openNetworkIcon: true,
openUseTurnIcon: true,
openCommRoom: true,
openRefleshRoom: true,
openNotice: true,
allowNumber: true,
allowChinese: true,
allowSymbol: true,
noticeMsgList:[]
})
})
return `
<style>
.layui-layer{
transition: all 0.5s cubic-bezier(0.18, 0.89, 0.32, 1.28) 0s;
}
.layuiadmin-span-color, .layuiadmin-big-font{
font-weight: bold;
}
.layui-table{
word-break: break-all;box-shadow: 10px 3px 15px 3px rgb(0 0 0 / 5%);
}
.room-recent-title{
margin-left: 10px;margin-top: 10px;font-weight: bold;font-size: 17px;
}
.room-status-svg{
width: 15px; height: 15px; top: 2px; position: relative;
}
.layui-form-item {
margin-top: 15px;
}
.switch-form .layui-input-block {
margin-left: 15px;
}
@media screen and (min-width: 445px){
.info-form .layui-form-item:first-child .layui-input-block {
display: inline-flex;
margin-left: 15px;
}
}
</style>
<div class="layui-fluid">
<div class="layui-row layui-col-space15" id="tl_console_setting_tpl_view">
<div class="layui-col-sm12">
<div class="layui-row layui-col-space15">
<div class="layui-col-sm12">
<div class="room-recent-title">数据传输功能开关设置</div>
<form class="layui-form switch-form" style="display: inline-flex; flex-wrap: wrap;" lay-filter="switch-form">
<div class="layui-form-item">
<div class="layui-input-block">
<input type="checkbox" name="openSendBug" title="开启意见反馈" lay-skin="primary">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<input type="checkbox" name="openScreen" title="开启网页录屏" lay-skin="primary">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<input type="checkbox" name="openScreenShare" title="开启屏幕共享" lay-skin="primary">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<input type="checkbox" name="openVideoShare" title="开启音视频通话" lay-skin="primary">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<input type="checkbox" name="openPasswordRoom" title="开启密码房间" lay-skin="primary">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<input type="checkbox" name="openOnlineUser" title="开启在线人数显示" lay-skin="primary">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<input type="checkbox" name="openShareRoom" title="开启房间链接分享" lay-skin="primary">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<input type="checkbox" name="openFileTransfer" title="开启文件传输" lay-skin="primary" checked disabled>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<input type="checkbox" name="openTxtTransfer" title="开启文本传输" lay-skin="primary" checked disabled>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<input type="checkbox" name="openTurnServer" title="开启中继设置" lay-skin="primary">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<input type="checkbox" name="openCommRoom" title="开启公共频道发言" lay-skin="primary">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<input type="checkbox" name="openGetCodeFile" title="开启取件码取件" lay-skin="primary">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<input type="checkbox" name="openAiChat" title="开启AI对话聊天" lay-skin="primary">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<input type="checkbox" name="openNotice" title="开启网站公告" lay-skin="primary">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<input type="checkbox" name="openRefleshRoom" title="开启随机刷新房间号" lay-skin="primary">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<input type="checkbox" name="openNetworkIcon" title="展示网络状态图标" lay-skin="primary">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<input type="checkbox" name="openUseTurnIcon" title="展示中继服务器图标" lay-skin="primary">
</div>
</div>
</form>
</div>
</div>
</div>
<div class="layui-col-sm12">
<div class="layui-row layui-col-space15">
<div class="layui-col-sm12">
<div class="room-recent-title">数据传输房间号格式设置</div>
<form class="layui-form info-form" lay-filter="info-form">
<div class="layui-form-item">
<div class="layui-block">
<div class="layui-input-block">
<input type="checkbox" name="allowNumber" title="允许数字格式" lay-skin="primary">
</div>
<div class="layui-input-block">
<input type="checkbox" name="allowChinese" title="允许中文格式" lay-skin="primary">
</div>
<div class="layui-input-block">
<input type="checkbox" name="allowSymbol" title="允许特殊字符格式" lay-skin="primary">
</div>
</div>
</div>
</form>
</div>
</div>
</div>
<div class="layui-col-sm12">
<div class="layui-row layui-col-space15">
<div class="layui-col-sm12">
<div class="room-recent-title">数据传输公告设置</div>
<form class="layui-form notice-form" lay-filter="notice-form">
<div class="layui-form-item" style="margin-top: 30px;">
<div class="layui-block">
<div class="layui-input-block" style="display: flex;margin-left: 0;">
<input type="text" name="noticeMsg" placeholder="发布公告内容" autocomplete="off"
class="layui-input">
<button type="button" lay-submit lay-filter="notice" class="layui-btn">发布</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script>
layui.use(['form'], function () {
window.$ = layui.$;
window.form = layui.form;
let switchData = ${resData.content}
form.val("switch-form",switchData)
form.val("info-form",switchData)
let noticeMsg = ""
if(switchData.noticeMsgList && switchData.noticeMsgList.length > 0){
noticeMsg = switchData.noticeMsgList[0].msg
}
form.val("notice-form",{
noticeMsg : noticeMsg
})
form.on('checkbox()', function(data){
if(switchData[data.elem.name] !== undefined || switchData[data.elem.name] !== null){
switchData[data.elem.name] = data.elem.checked
}
window.manageChange({
id : ${resData.id},
content : switchData
})
});
form.on('submit()', function(data){
switchData.noticeMsgList = [{
msg : data.field.noticeMsg
}]
window.manageChange({
id : ${resData.id},
content : switchData
})
});
});
</script>
`
}
module.exports = {
getSettingPageHtml
}

View File

@@ -0,0 +1,70 @@
const conf = require("../../../conf/cfg.json");
const request = require('request');
const qiwei = conf.notify.qiwei;
const open = conf.notify.open;
// 统计企微机器人发送map
const qiweiMap = {}
for (let key in qiwei) {
qiweiMap[qiwei[key]] = {
time: new Date().valueOf(),
count: 0
};
}
/**
* 企业微信通知
* @param {*} msg
*/
function requestMsg(msg) {
if(!open){
return
}
let finalKey = "";
for (let key in qiweiMap) {
// 单个还没达到20次直接用
if (qiweiMap[key].count < 20) {
qiweiMap[key].count += 1;
finalKey = key;
break;
} else {
//达到20次看看时间如果在1分钟内说明达到限制直接跳过
if ((new Date().valueOf() / 1000) - (qiweiMap[key].time / 1000) <= 60) {
continue;
} else {
//达到20次但是时间超过1分钟我们尝试清零
qiweiMap[key].count = 1;
qiweiMap[key].time = new Date().valueOf()
finalKey = key;
break;
}
}
}
if (finalKey === '' && qiwei.length > 0) {
finalKey = qiwei[0];
}
msg = msg + `机器人KEY: ${finalKey}\n`;
msg = msg + `机器人KEY列表: ${JSON.stringify(qiweiMap)}\n`;
request({
url: "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=" + finalKey,
method: "POST",
headers: {
"content-type": "application/json",
},
body: JSON.stringify({
msgtype: "markdown",
markdown: {
content: msg,
}
})
}, function (error, response, body) {
console.log('提示成功!', qiweiMap);
});
}
module.exports = {
requestMsg
}

View File

@@ -0,0 +1,327 @@
const notify = require("./notify");
const utils = require("./../../utils/utils");
/**
* 发送公共频道聊天通知
* @param {*} data
*/
function sendChatingNotify(data) {
let notifyMsg = `## <font color='info'>文件传输通知</font> - <font color="warning">${data.title}</font>` +
` - <font color="comment">${data.room}</font>\n` +
`库记录ID: ${data.recoderId}\n` +
`消息体ID: ${data.msgRecoderId}\n` +
`发送方ID: ${data.socketId}\n` +
`文本内容: ${decodeURIComponent(data.msg)}\n` +
`当前时间: ${utils.formateDateTime(new Date(), "yyyy-MM-dd hh:mm:ss")}\n` +
`访问IP: ${data.ip}\n` +
`访问设备: ${data.userAgent}\n`;
notify.requestMsg(notifyMsg)
}
/**
* 发送开始发送文件通知
* @param {*} data
*/
function sendFileInfoNotify(data) {
let notifyMsg = `## <font color='info'>文件传输通知</font> - <font color="warning">${data.title}</font>` +
` - <font color="comment">${data.room}</font>\n` +
`库记录ID: ${data.recoderId}\n` +
`发送方ID: ${data.from}\n` +
`文件名称: ${data.name}\n` +
`文件类型: ${data.type}\n` +
`文件大小: ${data.size} == (${data.size / 1024 / 1024}M)\n` +
`当前时间: ${utils.formateDateTime(new Date(), "yyyy-MM-dd hh:mm:ss")}\n` +
`访问IP: ${data.ip}\n` +
`访问设备: ${data.userAgent}\n`;
notify.requestMsg(notifyMsg)
}
/**
* 发送文件发送完毕通知
* @param {*} data
*/
function sendFileDoneNotify(data) {
let notifyMsg = `## <font color='info'>文件传输通知</font> - <font color="warning">${data.title}</font>` +
` - <font color="comment">${data.room}</font>\n` +
`发送方ID: ${data.from}\n` +
`接收方ID: ${data.to}\n` +
`文件名称: ${data.name}\n` +
`文件类型: ${data.type}\n` +
`文件大小: ${data.size} == (${data.size / 1024 / 1024}M)\n` +
`当前时间: ${utils.formateDateTime(new Date(), "yyyy-MM-dd hh:mm:ss")}\n` +
`访问IP: ${data.ip}\n` +
`访问设备: ${data.userAgent}\n`;
notify.requestMsg(notifyMsg)
}
/**
* 发送文本内容通知
* @param {*} data
*/
function sendTxtNotify(data) {
let notifyMsg = `## <font color='info'>文件传输通知</font> - <font color="warning">${data.title}</font>` +
` - <font color="comment">${data.room}</font>\n` +
`库记录ID: ${data.recoderId}\n` +
`发送方ID: ${data.from}\n` +
`文本内容: ${decodeURIComponent(data.content)}\n` +
`当前时间: ${utils.formateDateTime(new Date(), "yyyy-MM-dd hh:mm:ss")}\n` +
`访问IP: ${data.ip}\n` +
`访问设备: ${data.userAgent}\n`;
notify.requestMsg(notifyMsg)
}
/**
* 发送开始录屏通知
* @param {*} data
*/
function sendStartScreenNotify(data) {
let notifyMsg = `## <font color='info'>文件传输通知</font> - <font color="warning">${data.title}</font>\n` +
`当前时间: ${utils.formateDateTime(new Date(), "yyyy-MM-dd hh:mm:ss")}\n` +
`访问IP: ${data.ip}\n` +
`访问设备: ${data.userAgent}\n`;
notify.requestMsg(notifyMsg)
}
/**
* 发送停止录屏通知
* @param {*} data
*/
function sendStopScreenNotify(data) {
let notifyMsg = `## <font color='info'>文件传输通知</font> - <font color="warning">${data.title}</font>\n` +
`录屏时长: ${data.cost}\n` +
`录屏大小: ${data.size} == (${data.size / 1024 / 1024}M)\n` +
`当前时间: ${utils.formateDateTime(new Date(), "yyyy-MM-dd hh:mm:ss")}\n` +
`访问IP: ${data.ip}\n` +
`访问设备: ${data.userAgent}\n`;
notify.requestMsg(notifyMsg)
}
/**
* 发送开始屏幕共享通知
* @param {*} data
*/
function sendStartScreenShareNotify(data) {
let notifyMsg = `## <font color='info'>文件传输通知</font> - <font color="warning">${data.title}</font>` +
` - <font color="comment">${data.room}</font>\n` +
`当前时间: ${utils.formateDateTime(new Date(), "yyyy-MM-dd hh:mm:ss")}\n` +
`访问IP: ${data.ip}\n` +
`访问设备: ${data.userAgent}\n`;
notify.requestMsg(notifyMsg)
}
/**
* 发送停止屏幕共享通知
* @param {*} data
*/
function sendStopScreenShareNotify(data) {
let notifyMsg = `## <font color='info'>文件传输通知</font> - <font color="warning">${data.title}</font>` +
` - <font color="comment">${data.room}</font>\n` +
`共享时长: ${data.cost}\n` +
`当前时间: ${utils.formateDateTime(new Date(), "yyyy-MM-dd hh:mm:ss")}\n` +
`访问IP: ${data.ip}\n` +
`访问设备: ${data.userAgent}\n`;
notify.requestMsg(notifyMsg)
}
/**
* 发送开始音视频通话通知
* @param {*} data
*/
function sendStartVideoShareNotify(data) {
let notifyMsg = `## <font color='info'>文件传输通知</font> - <font color="warning">${data.title}</font>` +
` - <font color="comment">${data.room}</font>\n` +
`当前时间: ${utils.formateDateTime(new Date(), "yyyy-MM-dd hh:mm:ss")}\n` +
`访问IP: ${data.ip}\n` +
`访问设备: ${data.userAgent}\n`;
notify.requestMsg(notifyMsg)
}
/**
* 发送停止音视频通话通知
* @param {*} data
*/
function sendStopVideoShareNotify(data) {
let notifyMsg = `## <font color='info'>文件传输通知</font> - <font color="warning">${data.title}</font>` +
` - <font color="comment">${data.room}</font>\n` +
`通话时长: ${data.cost}\n` +
`当前时间: ${utils.formateDateTime(new Date(), "yyyy-MM-dd hh:mm:ss")}\n` +
`访问IP: ${data.ip}\n` +
`访问设备: ${data.userAgent}\n`;
notify.requestMsg(notifyMsg)
}
/**
* 发送取件码通知
* @param {*} data
*/
function sendCodeFileNotify(data) {
let notifyMsg = `## <font color='info'>文件传输通知</font> - <font color="warning">${data.title}</font>\n` +
`取件码ID: ${data.codeId}\n` +
`当前时间: ${utils.formateDateTime(new Date(), "yyyy-MM-dd hh:mm:ss")}\n` +
`访问IP: ${data.ip}\n` +
`访问设备: ${data.userAgent}\n`;
notify.requestMsg(notifyMsg)
}
/**
* 发送openai聊天通知
* @param {*} data
*/
function sendOpenaiChatNotify(data) {
let notifyMsg = `## <font color='info'>文件传输通知</font> - <font color="warning">${data.title}</font>` +
` - <font color="comment">${data.room}</font>\n` +
`KEYS状态: ${data.keys}\n` +
`聊天内容: ${data.content}\n` +
`回复内容: ${data.answer}\n` +
`当前时间: ${utils.formateDateTime(new Date(), "yyyy-MM-dd hh:mm:ss")}\n` +
`访问IP: ${data.ip}\n` +
`访问设备: ${data.userAgent}\n`;
notify.requestMsg(notifyMsg)
}
/**
* 发送意见反馈通知
* @param {*} data
*/
function sendBugNotify(data) {
let notifyMsg = `## <font color='info'>文件传输通知</font> - <font color="warning">${data.title}</font>\n` +
`反馈内容: ${data.msg}\n` +
`当前时间: ${utils.formateDateTime(new Date(), "yyyy-MM-dd hh:mm:ss")}\n` +
`访问IP: ${data.ip}\n` +
`访问设备: ${data.userAgent}\n`;
notify.requestMsg(notifyMsg)
}
/**
* 发送管理后台登录失败通知
* @param {*} data
*/
function sendManageLoginFailedNotify(data) {
let notifyMsg = `## <font color='info'>文件传输通知</font> - <font color="warning">${data.title}</font>` +
` - <font color="comment">${data.room}</font>\n` +
`访问密码: ${data.value}\n` +
`当前时间: ${utils.formateDateTime(new Date(), "yyyy-MM-dd hh:mm:ss")}\n` +
`访问IP: ${data.ip}\n` +
`访问设备: ${data.userAgent}\n`;
notify.requestMsg(notifyMsg)
}
/**
* 发送管理后台登录成功通知
* @param {*} data
*/
function sendManageLoginSuccessNotify(data) {
let notifyMsg = `## <font color='info'>文件传输通知</font> - <font color="warning">${data.title}</font>` +
` - <font color="comment">${data.room}</font>\n` +
`访问密码: ${data.value}\n` +
`TOKEN: ${data.token}\n` +
`当前时间: ${utils.formateDateTime(new Date(), "yyyy-MM-dd hh:mm:ss")}\n` +
`访问IP: ${data.ip}\n` +
`访问设备: ${data.userAgent}\n`;
notify.requestMsg(notifyMsg)
}
/**
* 发送管理后台修改配置通知
* @param {*} data
*/
function sendManageUpdateInfoNotify(data) {
let notifyMsg = `## <font color='info'>文件传输通知</font> - <font color="warning">${data.title}</font>` +
` - <font color="comment">${data.room}</font>\n` +
`修改内容: ${data.content}\n` +
`TOKEN: ${data.token}\n` +
`当前时间: ${utils.formateDateTime(new Date(), "yyyy-MM-dd hh:mm:ss")}\n` +
`访问IP: ${data.ip}\n` +
`访问设备: ${data.userAgent}\n`;
notify.requestMsg(notifyMsg)
}
/**
* 发送管理后台非法修改配置通知
* @param {*} data
*/
function sendManageUpdateFailedNotify(data) {
let notifyMsg = `## <font color='info'>文件传输通知</font> - <font color="warning">${data.title}</font>` +
` - <font color="comment">${data.room}</font>\n` +
`修改内容: ${data.content}\n` +
`TOKEN: ${data.token}\n` +
`当前时间: ${utils.formateDateTime(new Date(), "yyyy-MM-dd hh:mm:ss")}\n` +
`访问IP: ${data.ip}\n` +
`访问设备: ${data.userAgent}\n`;
notify.requestMsg(notifyMsg)
}
/**
* 发送创建/加入房间通知
* @param {*} data
*/
function sendCreateJoinRoomNotify(data) {
let notifyMsg = `## <font color='info'>文件传输通知</font> - <font color="warning">${data.title}</font>` +
` - <font color="comment">${data.room}</font>\n` +
`库记录ID: ${data.recoderId}\n` +
`连接方ID: ${data.socketId}\n` +
`房间密码: ${data.password}\n` +
`当前时间: ${utils.formateDateTime(new Date(), "yyyy-MM-dd hh:mm:ss")}\n` +
`访问IP: ${data.ip}\n` +
`访问设备: ${data.userAgent}\n`;
notify.requestMsg(notifyMsg)
}
/**
* 退出房间通知
* @param {*} data
*/
function sendExitRoomNotify(data) {
let notifyMsg = `## <font color='info'>文件传输通知</font> - <font color="warning">${data.title}</font>` +
` - <font color="comment">${data.room}</font>\n` +
`库记录ID: ${data.recoderId}\n` +
`连接方ID: ${data.socketId}\n` +
`当前时间: ${utils.formateDateTime(new Date(), "yyyy-MM-dd hh:mm:ss")}\n` +
`访问IP: ${data.ip}\n` +
`访问设备: ${data.userAgent}\n`;
notify.requestMsg(notifyMsg)
}
module.exports = {
sendExitRoomNotify,
sendCreateJoinRoomNotify,
sendManageUpdateFailedNotify,
sendManageUpdateInfoNotify,
sendManageLoginSuccessNotify,
sendManageLoginFailedNotify,
sendBugNotify,
sendStopScreenNotify,
sendStartScreenNotify,
sendStopScreenShareNotify,
sendStartScreenShareNotify,
sendStopVideoShareNotify,
sendStartVideoShareNotify,
sendTxtNotify,
sendCodeFileNotify,
sendFileDoneNotify,
sendFileInfoNotify,
sendChatingNotify,
sendOpenaiChatNotify
}

View File

@@ -4,7 +4,7 @@
*/
const request = require('request')
const openai = require('../../conf/cfg.json').openai
const openai = require('../../../conf/cfg.json').openai
let keysMap = {}
/**

View File

@@ -4,7 +4,7 @@
*/
const request = require('request');
const seafile = require('../../conf/cfg.json').oss.seafile
const seafile = require('../../../conf/cfg.json').oss.seafile
/**
* 获取token

117
src/bussiness/room/room.js Normal file
View File

@@ -0,0 +1,117 @@
const room = require("./../../dao/room/room");
/**
* 创建/加入房间数据入库
* @param {*} data
*/
async function createJoinRoom(data) {
let req = {
ctx: {
tables: data.tables
},
params: {
uid: "1",
uname: "user",
rname: data.roomName,
sid: data.socketId,
pwd: data.password,
ip: data.ip,
device: data.device,
url: data.url || "",
content: JSON.stringify(data.content)
}
};
let res = await room.createJoinRoom(req, null);
return res && res.dataValues ? res.dataValues.id : 0
}
/**
* 退出房间
* @param {*} data
*/
async function exitRoom(data) {
let req = {
ctx: {
tables: data.tables
},
params: {
sid: data.sid
}
};
let res = await room.exitRoomBySid(req, null);
console.log("退出成功 : ", data, res)
return 0;
}
/**
* 更新管理后台频道设置信息
* @param {*} data
*/
async function updateManageRoom(data) {
let req = {
ctx: {
tables: data.tables
},
params: {
id: data.id,
content: data.content
}
};
return await room.updateRoomContent(req, null);
}
/**
* 获取管理后台频道设置信息
* 管理频道房间号不存在就创建
* @param {*} data
*/
async function getOrCreateManageRoom(data) {
let req = {
ctx: {
tables: data.tables
},
params: {
sid: data.socketId,
ip: data.ip,
device: data.device,
content: data.content
}
};
return await room.getOrCreateManageRoom(req, null);
}
/**
* 获取加入/创建房间统计信息
* @param {*} data
* @returns
*/
async function getRoomHistoryInfo(data){
let req = {
ctx: {
tables: data.tables,
sockets : data.sockets,
dbClient : data.dbClient
},
params: {
limit : 10,
day : data.day
}
};
return await room.getRoomHistoryInfo(req, null);
}
module.exports = {
getOrCreateManageRoom,
updateManageRoom,
exitRoom,
createJoinRoom,
getRoomHistoryInfo
}

View File

@@ -1,97 +0,0 @@
const utils = require("../../utils/utils");
const conf = require("../../conf/cfg.json");
const request = require('request');
const wsConf = conf.ws;
const webrtcConf = conf.webrtc;
const qiwei = conf.notify.qiwei;
const open = conf.notify.open;
// 统计企微机器人发送map
const qiweiMap = {}
for (let key in qiwei) {
qiweiMap[qiwei[key]] = {
time: new Date().valueOf(),
count: 0
};
}
//获取ip地址,初始化等相关配置
function initData(req, res) {
var regexIP = /^((?:(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d?\d))$/;
let ip = utils.getLocalIP();
if (!regexIP.test(ip)) {
ip = utils.getClientIP(req)
}
if (!regexIP.test(ip)) {
ip = "127.0.0.1"
}
let data = {
wsHost: wsConf.ws_online ? wsConf.ws_online : "ws://" + ip + ":" + wsConf.port,
rtcConfig: { iceServers: webrtcConf.iceServers },
options: webrtcConf.options
};
res.json(data)
}
/**
* 企业微信通知
* @param {*} msg
*/
function requestMsg(msg) {
if(!open){
return
}
let finalKey = "";
for (let key in qiweiMap) {
// 单个还没达到20次直接用
if (qiweiMap[key].count < 20) {
qiweiMap[key].count += 1;
finalKey = key;
break;
} else {
//达到20次看看时间如果在1分钟内说明达到限制直接跳过
if ((new Date().valueOf() / 1000) - (qiweiMap[key].time / 1000) <= 60) {
continue;
} else {
//达到20次但是时间超过1分钟我们尝试清零
qiweiMap[key].count = 1;
qiweiMap[key].time = new Date().valueOf()
finalKey = key;
break;
}
}
}
if (finalKey === '' && qiwei.length > 0) {
finalKey = qiwei[0];
}
msg = msg + `机器人KEY: ${finalKey}\n`;
msg = msg + `机器人KEY列表: ${JSON.stringify(qiweiMap)}\n`;
request({
url: "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=" + finalKey,
method: "POST",
headers: {
"content-type": "application/json",
},
body: JSON.stringify({
msgtype: "markdown",
markdown: {
content: msg,
}
})
}, function (error, response, body) {
console.log('提示成功!', qiweiMap);
});
}
module.exports = {
initData,
requestMsg
}

View File

@@ -0,0 +1,33 @@
const utils = require("../../utils/utils");
const conf = require("../../../conf/cfg.json");
const wsConf = conf.ws;
const webrtcConf = conf.webrtc;
/**
* 获取ip地址,初始化等相关配置
* @param {*} req
* @param {*} res
*/
function initData(req, res) {
let regexIP = /^((?:(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d?\d))$/;
let ip = utils.getLocalIP();
if (!regexIP.test(ip)) {
ip = utils.getClientIP(req)
}
if (!regexIP.test(ip)) {
ip = "127.0.0.1"
}
let data = {
wsHost: wsConf.ws_online ? wsConf.ws_online : "ws://" + ip + ":" + wsConf.port,
rtcConfig: { iceServers: webrtcConf.iceServers },
options: webrtcConf.options
};
res.json(data)
}
module.exports = {
initData,
}

View File

@@ -1,9 +1,14 @@
const express = require('express');
const file = require("./file");
module.exports = function () {
const router = express.Router();
router.get("/dog", (req, res) => {
res.json({
dog : "request dog api ok!"
})
});
return router;
}

View File

@@ -1,9 +1,14 @@
const express = require('express');
const room = require("./room");
module.exports = function () {
const router = express.Router();
router.get("/room", (req, res) => {
res.json({
room : "request room api ok!"
})
});
return router;
}

23
src/controller/router.js Normal file
View File

@@ -0,0 +1,23 @@
const fs = require('fs');
const path = require('path');
const cfg = require("../../conf/cfg.json");
module.exports = () => {
let routers = {};
let handlerConf = cfg.router.filter;
let dirs = fs.readdirSync(__dirname);
for (let file of dirs) {
//过滤文件夹和文件
if (handlerConf.whiteDir.includes(file) || handlerConf.whiteFile.includes(file)) continue;
try {
//添加router
let stat = fs.statSync(path.join(__dirname, file, 'index.js'));
if (stat && stat.isFile()) {
routers["/api/" + file] = require("./" + file + '/index')();
}
} catch (e) {
console.log(e);
}
}
return routers;
}

View File

@@ -1,5 +1,5 @@
const utils = require("../../utils/utils");
const dbOpen = require("../../conf/cfg.json").db.open;
const dbOpen = require("../../../conf/cfg.json").db.open;
/**
* 添加操作dog数据
@@ -61,7 +61,7 @@ async function getDogManageInfo(req, res, next) {
let nextDay = utils.getNextDay(chooseDay);
//某日传输聚合列表
const [transferListToday, metadata] = await ctx.sql.query(`select name, room_id, content, handshake, created_at from dog where created_at >= "${chooseDay}" and created_at <= "${nextDay}" order by created_at desc`);
const [transferListToday, metadata] = await ctx.dbClient.query(`select name, room_id, content, handshake, created_at from dog where created_at >= "${chooseDay}" and created_at <= "${nextDay}" order by created_at desc`);
//发送文件
let fileTransferList = transferListToday.filter(element => {
@@ -113,7 +113,7 @@ async function getDogManageInfo(req, res, next) {
//全部数量统计
const [transferAll, metadata1] = await ctx.sql.query(`select name, count(*) as user from dog group by name`);
const [transferAll, metadata1] = await ctx.dbClient.query(`select name, count(*) as user from dog group by name`);
transferAll.forEach(element => {
if (element.name === '准备发送文件') {
data.transferFileAll += element.user
@@ -145,7 +145,7 @@ async function getDogManageInfo(req, res, next) {
async function getDogChating10Info(req, res, next) {
let ctx = req.ctx || {};
const [list, metadata] = await ctx.sql.query(`select name, room_id, content, socket_id, created_at from dog where name = '公共聊天室' order by created_at desc limit 10`);
const [list, metadata] = await ctx.dbClient.query(`select name, room_id, content, socket_id, created_at from dog where name = '公共聊天室' order by created_at desc limit 10`);
let resList = []
list.forEach(element => {

277
src/dao/room/room.js Normal file
View File

@@ -0,0 +1,277 @@
const utils = require("../../utils/utils");
const cfg = require("../../../conf/cfg.json")
const manageConfig = cfg.router.manage;
const dbOpen = cfg.db.open;
// 默认开关数据
const defaultSwitchData = {
openSendBug: true,
openScreen: true,
openOnlineUser: true,
openShareRoom: true,
openAiChat: true,
openGetCodeFile: true,
openVideoShare: true,
openPasswordRoom: true,
openScreenShare: true,
openFileTransfer: true,
openTxtTransfer: true,
openTurnServer: true,
openNetworkIcon: true,
openUseTurnIcon: true,
openCommRoom: true,
openRefleshRoom: true,
openNotice: true,
allowNumber: true,
allowChinese: true,
allowSymbol: true,
noticeMsgList: [],
}
/**
* 管理后台特殊房间入口、配置信息
* @param {*} req
* @param {*} res
* @param {*} next
*/
async function getOrCreateManageRoom(req, res, next) {
let ctx = req.ctx || {};
let params = req.params || {};
let data = {};
let manageRoomList = await ctx.tables.Room.findAll({
where: {
rname: manageConfig.room,
flag: 1
}
});
if (manageRoomList.length === 0) {
data = await ctx.tables.Room.create({
rcode: utils.genRoom(),
rname: manageConfig.room,
flag: 1,
sid: params.sid,
ip: params.ip,
device: params.device,
content: JSON.stringify(defaultSwitchData)
});
console.log("创建管理房间配置成功")
manageRoomList = await ctx.tables.Room.findAll({
where: {
rname: manageConfig.room,
flag: 1
}
});
}
manageRoomList = manageRoomList.length >= 1 ? manageRoomList[0] : manageRoomList
if (res) {
res.json(manageRoomList)
} else {
return manageRoomList;
}
}
/**
* 获取房间统计信息
* @param {*} req
* @param {*} res
* @param {*} next
*/
async function getRoomHistoryInfo(req, res, next) {
let ctx = req.ctx || {};
let params = req.params || {};
let sockets = ctx.sockets || {};
let data = {
createRoomToday: 0,
createRoomAll: 0,
joinRoomTodady: 0,
joinRoomAll: 0,
onlineRoomList: [],
todayRoomList: [],
userAgentIpList: []
};
//当前在线房间列表
for (let room in sockets.adapter.rooms) {
if (room.length > 15) {
continue
}
data.onlineRoomList.push({
status: "在线",
room: room,
userNumber: sockets.adapter.rooms[room] ? Object.keys(sockets.adapter.rooms[room].sockets).length : 0,
createTime: sockets.adapter.rooms[room].createTime
})
}
let day;
try {
day = new Date(params.day)
} catch (e) {
day = new Date()
}
let chooseDay = utils.formateDateTime(day, "yyyy-MM-dd");
let nextDay = utils.getNextDay(chooseDay);
// 某日房间聚合列表,数量统计
const [roomCoutingListToday, metadata] = await ctx.dbClient.query(
`select rname, any_value(created_at) as created_at, count(*) as user from room where created_at >= "${chooseDay}" and created_at <= "${nextDay}" group by rname order by created_at desc`);
data.createRoomToday += roomCoutingListToday.length;
roomCoutingListToday.forEach(element => {
data.joinRoomTodady += element.user;
data.todayRoomList.push({
room: element.rname,
count: element.user,
createTime: utils.formateDateTime(new Date(element.created_at), "yyyy-MM-dd hh:mm:ss"),
})
});
// 全部数量统计
const [roomCoutingListAll, metadata1] = await ctx.dbClient.query(`select count(*) as user from room group by rname`);
data.createRoomAll += roomCoutingListAll.length;
roomCoutingListAll.forEach(element => {
data.joinRoomAll += element.user
});
// 某日房间设备统计列表
const [roomListAgent, metadata2] = await ctx.dbClient.query(`select rname, content, created_at from room where created_at >= "${utils.formateDateTime(new Date(), "yyyy-MM-dd")}" order by created_at desc`);
roomListAgent.forEach(element => {
let content = JSON.parse(element.content);
if (content && content.handshake) {
data.userAgentIpList.push({
room: element.rname,
userAgent: content.handshake.headers['user-agent'],
Ip: content.handshake.headers['x-real-ip'] || content.handshake.headers['x-forwarded-for'] || content.handshake.headers['host'],
createTime: utils.formateDateTime(new Date(element.created_at), "yyyy-MM-dd hh:mm:ss"),
})
}
});
data.chooseDay = chooseDay;
if (res) {
res.json(data)
} else {
return data;
}
}
/**
* 创建/加入房间
* @param {*} req
* @param {*} res
* @param {*} next
*/
async function createJoinRoom(req, res, next) {
let ctx = req.ctx || {};
let params = req.params || {};
let data = {};
data = await ctx.tables.Room.create({
uid: params.uid,
uname: params.uname,
rcode: utils.genRoom(),
rname: params.rname,
sid: params.sid,
ip: params.ip,
device: params.device,
url: params.url,
content: params.content
});
if (res) {
res.json(data)
} else {
return data;
}
}
/**
* 更新房间
* @param {*} req
* @param {*} res
* @param {*} next
*/
async function updateRoomContent(req, res, next) {
let ctx = req.ctx || {};
let params = req.params || {};
let data = await ctx.tables.Room.update({
content: params.content,
}, {
where: {
id: params.id,
flag: 1
}
});
if (res) {
res.json(data)
} else {
return data;
}
}
/**
* 退出房间
* @param {*} req
* @param {*} res
* @param {*} next
*/
async function exitRoomBySid(req, res, next) {
let ctx = req.ctx || {};
let params = req.params || {};
console.log(ctx.tables)
let data = await ctx.tables.Room.update({
status: 1
}, {
where: {
sid: params.sid
}
});
if (res) {
res.json(data)
} else {
return data;
}
}
module.exports = dbOpen ? {
getRoomHistoryInfo,
createJoinRoom,
updateRoomContent,
exitRoomBySid,
getOrCreateManageRoom
} : {
getRoomHistoryInfo: () => {
return {}
},
createJoinRoom: () => {
return {}
},
updateRoomContent: () => {
return {}
},
exitRoomBySid: () => {
return {}
},
getOrCreateManageRoom: () => {
return {
content: JSON.stringify(defaultSwitchData)
}
},
}

View File

@@ -1,9 +0,0 @@
const express = require('express');
const dog = require("./dog");
module.exports = function () {
const router = express.Router();
return router;
}

View File

View File

@@ -1,276 +0,0 @@
const utils = require("../../utils/utils");
const manageConfig = require("../../conf/cfg.json").router.manage;
const dbOpen = require("../../conf/cfg.json").db.open;
// 默认开关数据
const defaultSwitchData = {
openSendBug: true,
openScreen: true,
openOnlineUser: true,
openShareRoom: true,
openAiChat: true,
openGetCodeFile: true,
openVideoShare: true,
openPasswordRoom: true,
openScreenShare: true,
openFileTransfer: true,
openTxtTransfer: true,
openTurnServer: true,
openNetworkIcon: true,
openUseTurnIcon: true,
openCommRoom: true,
openRefleshRoom: true,
openNotice: true,
allowNumber: true,
allowChinese: true,
allowSymbol: true,
noticeMsgList : [],
}
/**
* 管理后台特殊房间入口、配置信息
* @param {*} req
* @param {*} res
* @param {*} next
*/
async function getOrCreateManageRoom(req, res, next) {
let ctx = req.ctx || {};
let params = req.params || {};
let data = {};
let manageRoomList = await ctx.tables.Room.findAll({
where: {
rname: manageConfig.room,
flag :1
}
});
if (manageRoomList.length === 0) {
data = await ctx.tables.Room.create({
rcode: utils.genRoom(),
rname: manageConfig.room,
flag: 1,
sid: params.sid,
ip: params.ip,
device: params.device,
content: JSON.stringify(defaultSwitchData)
});
console.log("创建管理房间配置成功")
manageRoomList = await ctx.tables.Room.findAll({
where: {
rname: manageConfig.room,
flag :1
}
});
}
manageRoomList = manageRoomList.length >= 1 ? manageRoomList[0] : manageRoomList
if (res) {
res.json(manageRoomList)
} else {
return manageRoomList;
}
}
/**
* 获取房间统计信息
* @param {*} req
* @param {*} res
* @param {*} next
*/
async function getManageRoomInfo(req, res, next) {
let ctx = req.ctx || {};
let params = req.params || {};
let sockets = ctx.sockets || {};
let data = {
createRoomToday: 0,
createRoomAll: 0,
joinRoomTodady: 0,
joinRoomAll: 0,
onlineRoomList: [],
todayRoomList: [],
userAgentIpList: []
};
//当前在线房间列表
for (let room in sockets.adapter.rooms) {
if (room.length > 15) {
continue
}
data.onlineRoomList.push({
status: "在线",
room: room,
userNumber: sockets.adapter.rooms[room] ? Object.keys(sockets.adapter.rooms[room].sockets).length : 0,
createTime: sockets.adapter.rooms[room].createTime
})
}
let day;
try{
day = new Date(params.day)
}catch(e){
day = new Date()
}
let chooseDay = utils.formateDateTime(day, "yyyy-MM-dd");
let nextDay = utils.getNextDay(chooseDay);
// 某日房间聚合列表,数量统计
const [roomCoutingListToday, metadata] = await ctx.sql.query(
`select rname, any_value(created_at) as created_at, count(*) as user from room where created_at >= "${chooseDay}" and created_at <= "${nextDay}" group by rname order by created_at desc`);
data.createRoomToday += roomCoutingListToday.length;
roomCoutingListToday.forEach(element => {
data.joinRoomTodady += element.user;
data.todayRoomList.push({
room: element.rname,
count: element.user,
createTime: utils.formateDateTime(new Date(element.created_at), "yyyy-MM-dd hh:mm:ss"),
})
});
// 全部数量统计
const [roomCoutingListAll, metadata1] = await ctx.sql.query(`select count(*) as user from room group by rname`);
data.createRoomAll += roomCoutingListAll.length;
roomCoutingListAll.forEach(element => {
data.joinRoomAll += element.user
});
// 某日房间设备统计列表
const [roomListAgent, metadata2] = await ctx.sql.query(`select rname, content, created_at from room where created_at >= "${utils.formateDateTime(new Date(), "yyyy-MM-dd")}" order by created_at desc`);
roomListAgent.forEach(element => {
let content = JSON.parse(element.content);
if(content && content.handshake){
data.userAgentIpList.push({
room: element.rname,
userAgent: content.handshake.headers['user-agent'],
Ip: content.handshake.headers['x-real-ip'] || content.handshake.headers['x-forwarded-for'] || content.handshake.headers['host'],
createTime: utils.formateDateTime(new Date(element.created_at), "yyyy-MM-dd hh:mm:ss"),
})
}
});
data.chooseDay = chooseDay;
if (res) {
res.json(data)
} else {
return data;
}
}
/**
* 创建/加入房间
* @param {*} req
* @param {*} res
* @param {*} next
*/
async function createJoinRoom(req, res, next) {
let ctx = req.ctx || {};
let params = req.params || {};
let data = {};
data = await ctx.tables.Room.create({
uid: params.uid,
uname: params.uname,
rcode: utils.genRoom(),
rname: params.rname,
sid: params.sid,
ip: params.ip,
device: params.device,
url: params.url,
content: params.content
});
if (res) {
res.json(data)
} else {
return data;
}
}
/**
* 更新房间
* @param {*} req
* @param {*} res
* @param {*} next
*/
async function updateRoomContent(req, res, next) {
let ctx = req.ctx || {};
let params = req.params || {};
let data = await ctx.tables.Room.update({
content: params.content,
}, {
where: {
id: params.id,
flag : 1
}
});
if (res) {
res.json(data)
} else {
return data;
}
}
/**
* 退出房间
* @param {*} req
* @param {*} res
* @param {*} next
*/
async function exitRoomBySid(req, res, next) {
let ctx = req.ctx || {};
let params = req.params || {};
console.log(ctx.tables)
let data = await ctx.tables.Room.update({
status: 1
}, {
where: {
sid: params.sid
}
});
if (res) {
res.json(data)
} else {
return data;
}
}
module.exports = dbOpen ? {
getManageRoomInfo,
createJoinRoom,
updateRoomContent,
exitRoomBySid,
getOrCreateManageRoom
} : {
getManageRoomInfo : () => {
return {}
},
createJoinRoom : () => {
return {}
},
updateRoomContent : () => {
return {}
},
exitRoomBySid : () => {
return {}
},
getOrCreateManageRoom : () => {
return {
content : JSON.stringify(defaultSwitchData)
}
},
}

View File

@@ -1,24 +0,0 @@
const fs = require('fs');
const path = require('path');
module.exports = (conf) => {
let routers = {};
let handlerConf = conf.router.filter;
//file模块
let dirs = fs.readdirSync(__dirname);
for (let file of dirs) {
//过滤文件夹和文件
if(handlerConf.whiteDir.includes(file) || handlerConf.whiteFile.includes(file)) continue;
try {
//添加router
let stat = fs.statSync(path.join(__dirname, file, 'index.js'));
if (stat && stat.isFile()) {
routers["/api/"+file] = require("./" + file + '/index')();
}
} catch (e) {
console.log(e);
}
}
return routers;
}

File diff suppressed because it is too large Load Diff

89
src/socket/connect.js Normal file
View File

@@ -0,0 +1,89 @@
const rtcDisConnect = require("./rtcDisConnect/disconnect");
const rtcOffer = require("./rtcOffer/offer");
const rtcAnswer = require("./rtcAnswer/answer");
const rtcCandidate = require("./rtcCandidate/candidate");
const rtcCount = require("./rtcCount/count");
const rtcExit = require("./rtcExit/exit");
const rtcCommData = require("./rtcCommData/commData");
const rtcCreateJoin = require("./rtcCreateJoin/createJoin");
const rtcManageConfirm = require("./rtcManage/confirm");
const rtcManageChange = require("./rtcManage/change");
const rtcManageReload = require("./rtcManage/reload");
const rtcMessage = require("./rtcMessage/message");
const rtcChating = require("./rtcChating/chating");
const rtcOpenai = require("./rtcOpenai/openai");
module.exports = (io, socket, tables, dbClient) => {
rtcCount.count(io, socket, tables, dbClient, {})
// 断开连接
socket.on('disconnect', (data)=>{
rtcDisConnect.disconnect(io, socket, tables, dbClient, data)
});
// webrtc offer 消息
socket.on('offer', (data) => {
rtcOffer.offer(io, socket, tables, dbClient, data)
});
// webrtc answer 消息
socket.on('answer', (data) => {
rtcAnswer.answer(io, socket, tables, dbClient, data)
});
// webrtc candidate 消息
socket.on('candidate', (data) => {
rtcCandidate.candidate(io, socket, tables, dbClient, data)
});
// 在线人数统计
socket.on('count', (data) => {
rtcCount.count(io, socket, tables, dbClient, data)
});
// 退出房间
socket.on('exit', (data) => {
rtcExit.exit(io, socket, tables, dbClient, data)
});
// 获取初始数据
socket.on("getCommData", (data) => {
rtcCommData.commData(io, socket, tables, dbClient, data)
})
// 创建或加入房间
socket.on('createAndJoin', (data) => {
rtcCreateJoin.createJoin(io, socket, tables, dbClient, data)
});
// 管理后台登陆验证
socket.on('manageConfirm', (data) => {
rtcManageConfirm.confirm(io, socket, tables, dbClient, data)
});
// 管理后台修改数据
socket.on('manageChange', (data) => {
rtcManageChange.change(io, socket, tables, dbClient, data)
});
// 管理后台刷新
socket.on('manageReload', (data) => {
rtcManageReload.reload(io, socket, tables, dbClient, data)
});
// 公共消息
socket.on('message', (data) => {
rtcMessage.message(io, socket, tables, dbClient, data)
});
// 公共聊天频道
socket.on('chatingComm', (data) => {
rtcChating.chating(io, socket, tables, dbClient, data)
});
// openai聊天
socket.on('openai', (data) => {
rtcOpenai.openai(io, socket, tables, dbClient, data)
});
}

View File

@@ -1,745 +1,20 @@
const template = require("./template");
const seafile = require('../oss/seafile')
const openai = require("../openai/openai")
const SocketHandler = template.SocketHandler;
const {
router
} = require("../../conf/cfg.json");
const manageConfig = router.manage;
const {
genRoom,
formateDateTime
} = require("../../utils/utils");
const {
sendExitRoomNotify,
sendCreateJoinRoomNotify,
sendManageUpdateFailedNotify,
sendManageUpdateInfoNotify,
sendManageLoginSuccessNotify,
sendManageLoginFailedNotify,
sendBugNotify,
sendStopScreenNotify,
sendStartScreenNotify,
sendStopScreenShareNotify,
sendStartScreenShareNotify,
sendStopVideoShareNotify,
sendStartVideoShareNotify,
sendTxtNotify,
sendFileDoneNotify,
sendFileInfoNotify,
sendChatingNotify,
sendCodeFileNotify,
sendOpenaiChatNotify,
updateManageRoom,
exitRoom,
createJoinRoom,
dogData,
getOrCreateManageRoom,
getRoomPageHtml,
getDataPageHtml,
getSettingPageHtml,
getDogChating10Info
} = require("./bussiness");
// 数据表
let tables = {};
// 登陆token数组
let tokens = [];
// sql操作
let sql = {};
// 公共聊天数据
let chatingComm = []
// 开关数据
let cacheSwitchData = {};
// 通知事件定义
let opName = {
"sendFileInfo": "准备发送文件",
"sendDone": "文件发送完毕",
"sendBugs": "收到问题反馈",
"sendTxt": "发送文本内容",
"startScreen": "开始网页录屏",
"stopScreen": "停止网页录屏",
"startScreenShare": "开始屏幕共享",
"stopScreenShare": "停止屏幕共享",
"startVideoShare": "开始音视频通话",
"stopVideoShare": "停止音视频通话",
"startPasswordRoom": "创建密码房间",
"addCodeFile": "添加取货码文件",
"getCodeFile" : "取件码取件",
"openaiChat" : "ChatGPT聊天"
}
const connect = require("./connect");
/**
* 执行器
* @param {*} tabs
* @param {*} config
* @param {*} tables
* @param {*} dbClient
* @param {*} io
* @returns
*/
async function excute(tabs, sequelize, config) {
tables = tabs;
sql = sequelize;
let io = config.ws.io;
async function excute(tables, dbClient, io) {
if (io === undefined || io === null) {
console.error("init socket error ");
return;
}
//前置执行函数
if (config.ws.beforeInit) {
config.ws.beforeInit();
}
chatingComm = await getDogChating10Info({
tables: tables,
sql: sql,
});
listen(io);
//后置执行函数
if (config.ws.afterInit) {
config.ws.afterInit();
}
}
/**
* 监听函数
* @param {*} io
*/
function listen(io) {
io.sockets.on('connection', function (socket) {
var handler = new SocketHandler(io.sockets, socket);
// 通知一下在线人数
handler._count()
// 断开连接
socket.on('disconnect', async function (reason) {
handler._disconnect({});
await exitRoom({ sid: socket.id, tables: tables })
});
// ice
socket.on('offer', function (message) {
handler._offer(message, {})
});
// ice
socket.on('answer', function (message) {
handler._answer(message, {})
});
// ice
socket.on('candidate', function (message) {
handler._candidate(message, {})
});
// 在线人数统计
socket.on('count', function (message) {
handler._count(message, {})
});
// 退出
socket.on('exit', async function (message) {
try {
let recoderId = message.recoderId;
handler._exit(message, {})
if (recoderId != undefined) {
await exitRoom({ sid: socket.id, tables: tables })
let handshake = socket.handshake
let userAgent = handshake.headers['user-agent'].toString().substr(0, 255);
let ip = handshake.headers['x-real-ip'] || handshake.headers['x-forwarded-for'] || handshake.headers['host'];
sendExitRoomNotify({
title: "退出房间",
room: message.room,
socketId: socket.id,
recoderId: message.recoderId,
userAgent: userAgent,
ip: ip
})
}
} catch (e) {
handler._message({
room: message.room,
emitType: "tips",
to: socket.id,
msg: "系统错误"
}, {})
}
});
socket.on("getCommData", async function () {
let handshake = socket.handshake
let userAgent = handshake.headers['user-agent'].toString().substr(0, 255);
let ip = handshake.headers['x-real-ip'] || handshake.headers['x-forwarded-for'] || handshake.headers['host'];
let manageInfo = await getOrCreateManageRoom({
tables: tables,
sid: socket.id,
ip: ip,
device: userAgent,
content: ""
})
let switchData = JSON.parse(manageInfo.content)
if (switchData && switchData.keys) {
delete switchData.keys;
}
if(switchData){
cacheSwitchData = switchData
}
handler._message({
emitType: "commData",
switchData: switchData,
chatingCommData: chatingComm,
})
})
// 创建或加入房间
socket.on('createAndJoin', async function (message) {
try {
let room = message.room;
let type = message.type;
if (room && room.length > 15) {
room = room.toString().substr(0, 14);
}
let password = message.password || '';
if (password && password.length > 6) {
password = password.toString().substr(0, 6);
}
let handshake = socket.handshake
let userAgent = handshake.headers['user-agent'].toString().substr(0, 255);
let ip = handshake.headers['x-real-ip'] || handshake.headers['x-forwarded-for'] || handshake.headers['host'];
let recoderId = 0;
if (manageConfig.room !== room) {
recoderId = await createJoinRoom({
socketId: socket.id,
roomName: room,
ip: ip,
device: userAgent,
content: { handshake: handshake },
password: password,
tables: tables
});
}
handler._createAndJoin(message, {
created: { recoderId: recoderId },
joined: { recoderId: recoderId }
})
// 管理员房间
if (room === manageConfig.room) {
message.socketId = socket.id;
socket.emit("manageCheck", message)
}
sendCreateJoinRoomNotify({
title: recoderId === 0 ? "创建/加入后台管理房间" : "创建/加入房间",
password: password,
socketId: socket.id,
room: room,
recoderId: recoderId,
userAgent: userAgent,
ip: ip,
})
io.sockets.adapter.rooms[room].createTime = formateDateTime(new Date(), "yyyy-MM-dd hh:mm:ss")
} catch (e) {
console.log(e)
handler._message({
room: message.room,
emitType: "tips",
to: socket.id,
msg: "系统错误"
}, {})
}
});
// 管理后台登陆验证
socket.on('manageConfirm', async function (message) {
try {
let handshake = socket.handshake
let userAgent = handshake.headers['user-agent'].toString().substr(0, 255);
let ip = handshake.headers['x-real-ip'] || handshake.headers['x-forwarded-for'] || handshake.headers['host'];
if (message.value !== manageConfig.password || message.room !== manageConfig.room) {
handler._message({
room: message.room,
emitType: "tips",
to: socket.id,
msg: "秘钥不正确"
}, {})
sendManageLoginFailedNotify({
title: "管理后台登录失败",
room: message.room,
value: message.value,
userAgent: userAgent,
ip: ip
})
return
}
let token = genRoom();
tokens.push(token)
sendManageLoginSuccessNotify({
title: "管理后台登录成功",
token: token,
room: message.room,
value: message.value,
userAgent: userAgent,
ip: ip
})
socket.emit("manage", {
token: token,
socketId: socket.id,
title: manageConfig.title,
content: [{
title: "房间频道",
html: await getRoomPageHtml({
tables: tables,
sql: sql,
sockets: io.sockets,
day: formateDateTime(new Date(), "yyyy-MM-dd"),
})
}, {
title: "数据传输",
html: await getDataPageHtml({
tables: tables,
sql: sql,
sockets: io.sockets,
day: formateDateTime(new Date(), "yyyy-MM-dd"),
})
}, {
title: "其他设置",
html: await getSettingPageHtml({
tables: tables,
rname: message.room,
sid: socket.socketId,
ip: ip,
device: userAgent
})
}]
})
} catch (e) {
console.log(e)
handler._message({
room: message.room,
emitType: "tips",
to: socket.id,
msg: "系统错误"
}, {})
}
});
// 管理后台修改数据
socket.on('manageChange', async function (message) {
try {
let handshake = socket.handshake
let userAgent = handshake.headers['user-agent'].toString().substr(0, 255);
let ip = handshake.headers['x-real-ip'] || handshake.headers['x-forwarded-for'] || handshake.headers['host'];
if (!message.token || !tokens.includes(message.token)) {
sendManageUpdateFailedNotify({
title: "管理后台非法修改配置",
token: message.token,
room: message.room,
content: message.content,
userAgent: userAgent,
ip: ip
})
return
}
await updateManageRoom({
tables: tables,
id: message.id,
content: JSON.stringify(message.content)
})
sendManageUpdateInfoNotify({
title: "管理后台修改配置",
token: message.token,
room: message.room,
content: JSON.stringify(message.content),
userAgent: userAgent,
ip: ip
})
handler._message({
room: message.room,
emitType: "tips",
to: socket.id,
msg: "更新成功"
}, {})
//通知下全频道
let switchData = message.content
if (switchData && switchData.keys) {
delete switchData.keys;
}
if(switchData){
cacheSwitchData = switchData
}
handler._commDataChange({
switchData: switchData,
})
} catch (e) {
console.log(e)
handler._message({
room: message.room,
emitType: "tips",
to: socket.id,
msg: "系统错误"
}, {})
}
});
// 管理后台刷新
socket.on('manageReload', async function (message) {
try {
let handshake = socket.handshake
let userAgent = handshake.headers['user-agent'].toString().substr(0, 255);
let ip = handshake.headers['x-real-ip'] || handshake.headers['x-forwarded-for'] || handshake.headers['host'];
if (!message.token || !tokens.includes(message.token)) {
sendManageUpdateFailedNotify({
title: "管理后台非法刷新数据",
token: message.token,
room: message.room,
content: message.content,
userAgent: userAgent,
ip: ip
})
return
}
socket.emit("manage", {
token: message.token,
socketId: socket.id,
title: manageConfig.title,
content: [{
title: "房间频道",
html: await getRoomPageHtml({
tables: tables,
sql: sql,
sockets: io.sockets,
day: message.content,
})
}, {
title: "数据传输",
html: await getDataPageHtml({
tables: tables,
sql: sql,
sockets: io.sockets,
day: message.content,
})
}, {
title: "其他设置",
html: await getSettingPageHtml({
tables: tables,
rname: message.room,
sid: socket.socketId,
ip: ip,
device: userAgent
})
}]
})
sendManageUpdateInfoNotify({
title: "管理后台重新获取配置",
token: message.token,
room: message.room,
content: JSON.stringify(message.content),
userAgent: userAgent,
ip: ip
})
} catch (e) {
console.log(e)
handler._message({
room: message.room,
emitType: "tips",
to: socket.id,
msg: "系统错误"
}, {})
}
});
// 公共消息
socket.on('message', async function (message) {
try {
let emitType = message.emitType;
let handshake = socket.handshake
let userAgent = handshake.headers['user-agent'].toString().substr(0, 255);
let ip = handshake.headers['x-real-ip'] || handshake.headers['x-forwarded-for'] || handshake.headers['host'];
handler._message(message, {})
if (emitType === 'sendFileInfo') {
sendFileInfoNotify({
title: opName.sendFileInfo,
room: message.room,
recoderId: message.recoderId,
from: message.from,
name: message.name,
type: message.type,
size: message.size,
userAgent: userAgent,
ip: ip
})
}
if (emitType === 'sendDone') {
sendFileDoneNotify({
title: opName.sendDone,
room: message.room,
to: message.to,
from: message.from,
name: message.name,
type: message.type,
size: message.size,
userAgent: userAgent,
ip: ip
})
}
if (emitType === 'sendBugs') {
sendBugNotify({
title: opName.sendBugs,
room: message.room,
msg: message.msg,
userAgent: userAgent,
ip: ip
})
}
if (emitType === 'sendTxt') {
sendTxtNotify({
title: opName.sendTxt,
room: message.room,
from: message.from,
recoderId: message.recoderId,
content: message.content,
userAgent: userAgent,
ip: ip
})
}
if (emitType === 'startScreen') {
sendStartScreenNotify({
title: opName.startScreen,
userAgent: userAgent,
ip: ip
})
}
if (emitType === 'stopScreen') {
sendStopScreenNotify({
title: opName.stopScreen,
userAgent: message.userAgent,
cost: message.cost,
size: message.size,
userAgent: userAgent,
ip: ip
})
}
if (emitType === 'startScreenShare') {
sendStartScreenShareNotify({
title: opName.startScreenShare,
userAgent: userAgent,
ip: ip,
room: message.room
})
}
if (emitType === 'stopScreenShare') {
sendStopScreenShareNotify({
title: opName.stopScreenShare,
userAgent: message.userAgent,
cost: message.cost,
userAgent: userAgent,
ip: ip,
room: message.room
})
}
if (emitType === 'startVideoShare') {
sendStartVideoShareNotify({
title: opName.startVideoShare,
userAgent: userAgent,
ip: ip,
room: message.room
})
}
if (emitType === 'stopVideoShare') {
sendStopVideoShareNotify({
title: opName.stopVideoShare,
userAgent: message.userAgent,
cost: message.cost,
userAgent: userAgent,
ip: ip,
room: message.room
})
}
if (opName[message.emitType]) {
await dogData({
tables: tables,
name: opName[message.emitType],
roomId: "",
socketId: "",
device: userAgent,
flag: 0,
content: JSON.stringify(message),
handshake: JSON.stringify(handshake),
ip: ip
});
}
} catch (e) {
console.log(e)
handler._message({
room: message.room,
emitType: "tips",
to: socket.id,
msg: "系统错误"
}, {})
}
});
// 公共聊天频道
socket.on('chatingComm', async function (message) {
try {
if(!cacheSwitchData.openCommRoom){
handler._message({
room: message.room,
emitType: "tips",
to: socket.id,
msg: "当前功能已暂时关闭,有问题可以加群交流"
}, {})
return
}
message.time = new Date().toLocaleString()
if (chatingComm.length < 10) {
chatingComm.push(message)
} else {
chatingComm.shift()
chatingComm.push(message)
}
handler._chatingComm(message, {})
let handshake = socket.handshake
let userAgent = handshake.headers['user-agent'].toString().substr(0, 255);
let ip = handshake.headers['x-real-ip'] || handshake.headers['x-forwarded-for'] || handshake.headers['host'];
let recoderId = await dogData({
name: "公共聊天室",
tables: tables,
roomId: message.room,
socketId: message.socketId,
device: userAgent,
flag: 0,
content: message.msg,
handshake: JSON.stringify(handshake),
ip: ip
});
sendChatingNotify({
title: '公共聊天频道',
room: message.room,
recoderId: recoderId,
msgRecoderId: recoderId,
socketId: message.socketId,
msg: message.msg,
userAgent: userAgent,
ip: ip
})
} catch (e) {
console.log(e)
handler._message({
room: message.room,
emitType: "tips",
to: socket.id,
msg: "系统错误"
}, {})
}
});
// openai聊天
socket.on('openai', async function (message) {
if(!cacheSwitchData.openAiChat){
handler._message({
room: message.room,
emitType: "tips",
to: socket.id,
msg: "当前功能已暂时关闭,有问题可以加群交流"
}, {})
return
}
let roomId = message.room || 10086;
let content = message.content;
let value = message.value;
if(value){
value = value.substr(0, 1000)
}
// 有上下文,结合上下文
if(content){
content = content.substr(0, 5000);
content += "。\n假定以上的内容是提问者和你的对话结合上面的语境回答下面的问题并且注意如果提问内容或者你的回答内容涉及政治请回复 “我已经被设置关闭涉政问答功能”。提问内容为 : "+value;
}else{
// 没有就默认
content = value;
}
let handshake = socket.handshake
let userAgent = handshake.headers['user-agent'].toString().substr(0, 255);
let ip = handshake.headers['x-real-ip'] || handshake.headers['x-forwarded-for'] || handshake.headers['host'];
message.time = new Date().toLocaleString()
message.type = "openai";
message.content = await openai.openaiChat(content, roomId);
message.value = "";
handler._openaiChat(message)
await dogData({
name: opName.openaiChat,
tables: tables,
roomId: roomId,
socketId: message.socketId,
device: userAgent,
flag: 0,
content: decodeURIComponent(message.content),
handshake: JSON.stringify(handshake),
ip: ip
});
sendOpenaiChatNotify({
title: opName.openaiChat,
room: roomId,
keys : JSON.stringify(openai.apiKeysStatus()),
content: content,
answer : message.content,
userAgent: userAgent,
ip: ip
})
});
connect(io, socket, tables, dbClient)
});
}

View File

@@ -0,0 +1,21 @@
/**
* webrtc answer
* 转发answer消息至room其他客户端 [from,to,room,sdp]
* @param {*} io socketio对象
* @param {*} socket 单个socket连接
* @param {*} tables 数据表对象
* @param {*} dbClient sequelize-orm对象
* @param {*} data event参数
* @returns
*/
async function answer(io, socket, tables, dbClient, data){
let otherClient = io.sockets.connected[data.to];
if (!otherClient) {
return;
}
otherClient.emit('answer', data);
}
module.exports = {
answer
}

View File

@@ -0,0 +1,21 @@
/**
* webrtc candidate
* 转发candidate消息至room其他客户端 [from,to,room,candidate[sdpMid,sdpMLineIndex,sdp]]
* @param {*} io socketio对象
* @param {*} socket 单个socket连接
* @param {*} tables 数据表对象
* @param {*} dbClient sequelize-orm对象
* @param {*} data event参数
* @returns
*/
async function candidate(io, socket, tables, dbClient, data){
let otherClient = io.sockets.connected[data.to];
if (!otherClient){
return;
}
otherClient.emit('candidate', data);
}
module.exports = {
candidate
}

View File

@@ -0,0 +1,80 @@
const bussinessDog = require("./../../bussiness/dog/dog")
const rtcMessage = require("./../rtcMessage/message");
const bussinessNotify = require("./../../bussiness/notify/notifySocketEvent")
const rtcCommData = require("./../rtcCommData/commData");
const utils = require("./../../utils/utils");
/**
* 公共聊天频道
* @param {*} io socketio对象
* @param {*} socket 单个socket连接
* @param {*} tables 数据表对象
* @param {*} dbClient sequelize-orm对象
* @param {*} data event参数
* @returns
*/
async function chating(io, socket, tables, dbClient, data){
try {
let cacheSwitchData = rtcCommData.getCacheSwitchData()
let chatingComm = rtcCommData.getChatingComm()
if(!cacheSwitchData.openCommRoom){
rtcMessage.message(io, socket, tables, dbClient, {
room: data.room,
emitType: "tips",
to: socket.id,
msg: "当前功能已暂时关闭,有问题可以加群交流"
})
return
}
data.time = new Date().toLocaleString()
if (chatingComm.length < 10) {
chatingComm.push(data)
} else {
chatingComm.shift()
chatingComm.push(data)
}
rtcCommData.setChatingComm(chatingComm);
io.sockets.emit("chatingComm", data);
let {handshake, userAgent, ip} = utils.getSocketClientInfo(socket);
let recoderId = await bussinessDog.dogData({
name: "公共聊天室",
tables: tables,
roomId: data.room,
socketId: data.socketId,
device: userAgent,
flag: 0,
content: decodeURIComponent(data.msg),
handshake: JSON.stringify(handshake),
ip: ip
});
bussinessNotify.sendChatingNotify({
title: '公共聊天频道',
room: data.room,
recoderId: recoderId,
msgRecoderId: recoderId,
socketId: data.socketId,
msg: decodeURIComponent(data.msg),
userAgent: userAgent,
ip: ip
})
} catch (e) {
console.log(e)
rtcMessage.message(io, socket, tables, dbClient, {
room: data.room,
emitType: "tips",
to: socket.id,
msg: "系统错误"
})
}
}
module.exports = {
chating
}

View File

@@ -0,0 +1,89 @@
const bussinessRoom = require("./../../bussiness/room/room")
const bussinessDog = require("./../../bussiness/dog/dog")
const rtcMessage = require("./../rtcMessage/message");
const utils = require("./../../utils/utils");
// 公共聊天数据缓存
let chatingComm = null
// 开关数据缓存
let cacheSwitchData = null
/**
* 获取初始数据
* @param {*} io socketio对象
* @param {*} socket 单个socket连接
* @param {*} tables 数据表对象
* @param {*} dbClient sequelize-orm对象
* @param {*} data event参数
* @returns
*/
async function commData(io, socket, tables, dbClient, data){
let {handshake, userAgent, ip} = utils.getSocketClientInfo(socket);
let manageInfo = await bussinessRoom.getOrCreateManageRoom({
tables: tables,
sid: socket.id,
ip: ip,
device: userAgent,
content: ""
})
let switchData = JSON.parse(manageInfo.content)
if(switchData){
cacheSwitchData = switchData
}
if(!chatingComm){
chatingComm = await bussinessDog.getDogChating10Info({
tables, dbClient
});
}
rtcMessage.message(io, socket, tables, dbClient, {
emitType: "commData",
switchData: switchData,
chatingCommData: chatingComm || [],
})
}
/**
* 获取 chatingComm
* @returns
*/
function getChatingComm(){
return chatingComm;
}
/**
* 更新 chatingComm
* @returns
*/
function setChatingComm(data){
chatingComm = data
return chatingComm;
}
/**
* 获取 cacheSwitchData
* @returns
*/
function getCacheSwitchData(){
return cacheSwitchData;
}
/**
* 更新 cacheSwitchData
* @param {*} data
*/
function setCacheSwitchData(data){
cacheSwitchData = data
return cacheSwitchData;
}
module.exports = {
commData,
getCacheSwitchData,
setCacheSwitchData,
getChatingComm,
setChatingComm
}

View File

@@ -0,0 +1,23 @@
/**
* 在线人数统计广播
* @param {*} io socketio对象
* @param {*} socket 单个socket连接
* @param {*} tables 数据表对象
* @param {*} dbClient sequelize-orm对象
* @param {*} data event参数
* @returns
*/
async function count(io, socket, tables, dbClient, data){
try{
let allManCount = Object.keys(io.sockets.connected).length || 0;
io.sockets.emit("count", {
mc : allManCount
})
}catch(e){
console.log(e)
}
}
module.exports = {
count
}

View File

@@ -0,0 +1,241 @@
const bussinessRoom = require("./../../bussiness/room/room")
const bussinessNotify = require("./../../bussiness/notify/notifySocketEvent")
const rtcCount = require("./../rtcCount/count");
const rtcMessage = require("./../rtcMessage/message");
const utils = require("./../../utils/utils");
const cfg = require("./../../../conf/cfg.json")
/**
* 用户创建或加入房间
* @param {*} io
* @param {*} socket
* @param {*} tables
* @param {*} dbClient
* @param {*} data
* @returns
*/
async function userCreateAndJoin(io, socket, tables, dbClient, data){
let {handshake, userAgent, ip} = utils.getSocketClientInfo(socket);
let {room, type, nickName, password = ''} = data;
if (room && room.length > 15) {
room = room.toString().substr(0, 14);
}
if(nickName && nickName.length > 20){
nickName = nickName.substr(0, 20);
}
//设置昵称
io.sockets.connected[socket.id].nickName = nickName;
if(password && password.length > 6){
password = password.toString().substr(0,6);
}
let recoderId = await bussinessRoom.createJoinRoom({
socketId: socket.id,
roomName: room,
ip: ip,
device: userAgent,
content: { handshake: handshake },
password: password,
tables: tables
});
let clientsInRoom = io.sockets.adapter.rooms[room];
let numClients = clientsInRoom ? Object.keys(clientsInRoom.sockets).length : 0;
if (numClients === 0) {
socket.join(room);
socket.emit('created', {
id: socket.id,
room: room,
nickName : nickName,
peers: [],
type: type,
recoderId : recoderId
});
//密码房间 首次创建设置密码
if(type === 'password'){
io.sockets.adapter.rooms[room].password = password
}
}else {
//流媒体房间只允许两个人同时在线
if((type === 'screen' || type === 'video') && numClients >= 2){
socket.emit("tips", {
room : data.room,
to : socket.id,
msg : "当前房间已满,请开启其他房间号发起操作"
});
return
}
// 密码房间,检查密码
if(type === 'password'){
let roomPassword = io.sockets.adapter.rooms[room].password;
if(roomPassword !== password){
socket.emit("tips", {
room : data.room,
nickName : nickName,
to : socket.id,
msg : "密码错误",
reload : true
});
return
}
}
io.sockets.in(room).emit('joined',{
id: socket.id,
room: room,
nickName : nickName,
type: type,
recoderId : recoderId
});
let peers = new Array();
let otherSocketIds = Object.keys(clientsInRoom.sockets);
for (let i = 0; i < otherSocketIds.length; i++) {
let otherSocketId = otherSocketIds[i]
let peerNickName = io.sockets.connected[otherSocketId].nickName
peers.push({
id: otherSocketId,
nickName: peerNickName
});
}
socket.join(room);
socket.emit('created', {
id: socket.id,
room: room,
nickName : nickName,
peers: peers,
type: type,
recoderId : recoderId
});
}
rtcCount.count(io, socket, tables, dbClient, data);
io.sockets.adapter.rooms[room].createTime = utils.formateDateTime(new Date(), "yyyy-MM-dd hh:mm:ss")
bussinessNotify.sendCreateJoinRoomNotify({
title: "用户创建/加入房间",
password: password,
socketId: socket.id,
room: room,
recoderId: recoderId,
userAgent: userAgent,
ip: ip,
})
}
/**
* 管理员创建或加入房间
* @param {*} io
* @param {*} socket
* @param {*} tables
* @param {*} dbClient
* @param {*} data
* @returns
*/
async function manageCreateAndJoin(io, socket, tables, dbClient, data){
let {handshake, userAgent, ip} = utils.getSocketClientInfo(socket);
let {room, nickName} = data;
if (room && room.length > 15) {
room = room.toString().substr(0, 14);
}
if(nickName && nickName.length > 20){
nickName = nickName.substr(0, 20);
}
//设置昵称
io.sockets.connected[socket.id].nickName = nickName;
let clientsInRoom = io.sockets.adapter.rooms[room];
let numClients = clientsInRoom ? Object.keys(clientsInRoom.sockets).length : 0;
if(numClients > 0){
socket.emit("tips", {
room : data.room,
to : socket.id,
msg : "管理员房间已被登录"
});
return
}
socket.join(room);
socket.emit('created', {
id: socket.id,
room: room,
nickName : nickName,
peers: [],
recoderId : 0
});
io.sockets.adapter.rooms[room].createTime = utils.formateDateTime(new Date(), "yyyy-MM-dd hh:mm:ss")
rtcCount.count(io, socket, tables, dbClient, data);
// 下一步,让管理员输入密码
data.socketId = socket.id;
socket.emit("manageCheck", data)
bussinessNotify.sendCreateJoinRoomNotify({
title: "管理员创建/加入后台管理房间",
password: "",
socketId: socket.id,
room: room,
recoderId: 0,
userAgent: userAgent,
ip: ip,
})
}
/**
* 创建或加入房间
* @param {*} io socketio对象
* @param {*} socket 单个socket连接
* @param {*} tables 数据表对象
* @param {*} dbClient sequelize-orm对象
* @param {*} data event参数
* @returns
*/
async function createJoin(io, socket, tables, dbClient, data){
try {
let room = data.room;
if (room && room.length > 15) {
room = room.toString().substr(0, 14);
}
if (cfg.router.manage.room !== room) {
// 用户加入/创建房间
userCreateAndJoin(io, socket, tables, dbClient, data)
}else{
//管理员是一个专属房间,不能创建记录
manageCreateAndJoin(io, socket, tables, dbClient, data)
}
} catch (e) {
console.log(e)
rtcMessage.message(io, socket, tables, dbClient, {
room: data.room,
emitType: "tips",
to: socket.id,
msg: "系统错误"
})
}
}
module.exports = {
createJoin
}

View File

@@ -0,0 +1,24 @@
const bussinessRoom = require("./../../bussiness/room/room")
const rtcCount = require("./../rtcCount/count");
/**
* 断开连接的操作
* @param {*} io socketio对象
* @param {*} socket 单个socket连接
* @param {*} tables 数据表对象
* @param {*} dbClient sequelize-orm对象
* @param {*} data event参数
*/
async function disconnect(io, socket, tables, dbClient, data){
socket.broadcast.emit('exit', {
from : socket.id,
});
await bussinessRoom.exitRoom({ sid: socket.id, tables: tables });
rtcCount.count(io, socket, tables, dbClient, data)
}
module.exports = {
disconnect
}

View File

@@ -0,0 +1,60 @@
const bussinessRoom = require("./../../bussiness/room/room")
const bussinessNotify = require("./../../bussiness/notify/notifySocketEvent")
const rtcCount = require("./../rtcCount/count");
const rtcMessage = require("./../rtcMessage/message");
const utils = require("./../../utils/utils");
/**
* 退出房间
* @param {*} io socketio对象
* @param {*} socket 单个socket连接
* @param {*} tables 数据表对象
* @param {*} dbClient sequelize-orm对象
* @param {*} data event参数
* @returns
*/
async function exit(io, socket, tables, dbClient, data){
try {
let room = data.room;
socket.leave(room);
let clientsInRoom = io.sockets.adapter.rooms[room];
if (clientsInRoom) {
let otherSocketIds = Object.keys(clientsInRoom.sockets);
for (let i = 0; i < otherSocketIds.length; i++) {
let otherSocket = io.sockets.connected[otherSocketIds[i]];
otherSocket.emit('exit', data);
}
}
let recoderId = data.recoderId;
if (recoderId != undefined) {
await bussinessRoom.exitRoom({ sid: socket.id, tables })
let {handshake, userAgent, ip} = utils.getSocketClientInfo(socket);
bussinessNotify.sendExitRoomNotify({
title: "退出房间",
room: data.room,
socketId: socket.id,
recoderId: data.recoderId,
userAgent: userAgent,
ip: ip
})
}
rtcCount.count(io, socket, tables, dbClient, data)
} catch (e) {
rtcMessage.message(io, socket, tables, dbClient, {
room: data.room,
emitType: "tips",
to: socket.id,
msg: "系统错误"
})
}
}
module.exports = {
exit
}

View File

@@ -0,0 +1,79 @@
const bussinessNotify = require("./../../bussiness/notify/notifySocketEvent")
const bussinessRoom = require("./../../bussiness/room/room")
const rtcMessage = require("./../rtcMessage/message");
const rtcConfirm = require("./confirm");
const rtcCommData = require("./../rtcCommData/commData")
const utils = require("./../../utils/utils");
/**
* 管理后台修改数据
* @param {*} io socketio对象
* @param {*} socket 单个socket连接
* @param {*} tables 数据表对象
* @param {*} dbClient sequelize-orm对象
* @param {*} data event参数
* @returns
*/
async function change(io, socket, tables, dbClient, data){
try {
let {handshake, userAgent, ip} = utils.getSocketClientInfo(socket);
let tokens = rtcConfirm.getTokenList();
if (!data.token || !tokens.includes(data.token)) {
bussinessNotify.sendManageUpdateFailedNotify({
title: "管理后台非法修改配置",
token: data.token,
room: data.room,
content: data.content,
userAgent: userAgent,
ip: ip
})
return
}
await bussinessRoom.updateManageRoom({
tables: tables,
id: data.id,
content: JSON.stringify(data.content)
})
bussinessNotify.sendManageUpdateInfoNotify({
title: "管理后台修改配置",
token: data.token,
room: data.room,
content: JSON.stringify(data.content),
userAgent: userAgent,
ip: ip
})
rtcMessage.message(io, socket, tables, dbClient, {
room: data.room,
emitType: "tips",
to: socket.id,
msg: "更新成功"
})
//更新下缓存,通知下全频道
let switchData = data.content
if(switchData){
rtcCommData.setCacheSwitchData(switchData)
}
io.sockets.emit("commData", {
switchData : switchData
})
} catch (e) {
console.log(e)
rtcMessage.message(io, socket, tables, dbClient, {
room: data.room,
emitType: "tips",
to: socket.id,
msg: "系统错误"
})
}
}
module.exports = {
change
}

View File

@@ -0,0 +1,105 @@
const bussinessManageDataPage = require("./../../bussiness/manage/dataPage")
const bussinessManageRoomPage = require("./../../bussiness/manage/roomPage")
const bussinessManageSettingPage = require("./../../bussiness/manage/settingPage")
const bussinessNotify = require("./../../bussiness/notify/notifySocketEvent")
const rtcMessage = require("./../rtcMessage/message");
const utils = require("./../../utils/utils");
const cfg = require("./../../../conf/cfg.json")
const manageConfig = cfg.router.manage
// 登陆token列表
let tokens = [];
/**
* 管理后台登陆验证密码
* @param {*} io socketio对象
* @param {*} socket 单个socket连接
* @param {*} tables 数据表对象
* @param {*} dbClient sequelize-orm对象
* @param {*} data event参数
* @returns
*/
async function confirm(io, socket, tables, dbClient, data){
try {
let {handshake, userAgent, ip} = utils.getSocketClientInfo(socket);
if (data.value !== manageConfig.password || data.room !== manageConfig.room) {
rtcMessage.message(io, socket, tables, dbClient, {
room: data.room,
emitType: "tips",
to: socket.id,
msg: "秘钥不正确"
})
bussinessNotify.sendManageLoginFailedNotify({
title: "管理后台登录失败",
room: data.room,
value: data.value,
userAgent: userAgent,
ip: ip
})
return
}
let token = utils.genRoom();
tokens.push(token)
bussinessNotify.sendManageLoginSuccessNotify({
title: "管理后台登录成功",
token: token,
room: data.room,
value: data.value,
userAgent: userAgent,
ip: ip
})
socket.emit("manage", {
token: token,
socketId: socket.id,
title: manageConfig.title,
content: [{
title: "房间频道",
html: await bussinessManageRoomPage.getRoomPageHtml({
tables: tables,
dbClient: dbClient,
sockets: io.sockets,
day: utils.formateDateTime(new Date(), "yyyy-MM-dd"),
})
}, {
title: "数据传输",
html: await bussinessManageDataPage.getDataPageHtml({
tables: tables,
dbClient: dbClient,
sockets: io.sockets,
day: utils.formateDateTime(new Date(), "yyyy-MM-dd"),
})
}, {
title: "其他设置",
html: await bussinessManageSettingPage.getSettingPageHtml({
tables: tables,
rname: data.room,
sid: socket.socketId,
ip: ip,
device: userAgent
})
}]
})
} catch (e) {
console.log(e)
rtcMessage.message(io, socket, tables, dbClient, {
room: data.room,
emitType: "tips",
to: socket.id,
msg: "系统错误"
})
}
}
function getTokenList(){
return tokens;
}
module.exports = {
confirm,
getTokenList
}

View File

@@ -0,0 +1,91 @@
const bussinessManageDataPage = require("./../../bussiness/manage/dataPage")
const bussinessManageRoomPage = require("./../../bussiness/manage/roomPage")
const bussinessManageSettingPage = require("./../../bussiness/manage/settingPage")
const bussinessNotify = require("./../../bussiness/notify/notifySocketEvent")
const rtcMessage = require("./../rtcMessage/message");
const rtcConfirm = require("./confirm");
const utils = require("./../../utils/utils");
const cfg = require("./../../../conf/cfg.json")
const manageConfig = cfg.router.manage
/**
* 管理后台登陆验证
* @param {*} io socketio对象
* @param {*} socket 单个socket连接
* @param {*} tables 数据表对象
* @param {*} dbClient sequelize-orm对象
* @param {*} data event参数
* @returns
*/
async function reload(io, socket, tables, dbClient, data){
try {
let {handshake, userAgent, ip} = utils.getSocketClientInfo(socket);
let tokens = rtcConfirm.getTokenList();
if (!data.token || !tokens.includes(data.token)) {
bussinessNotify.sendManageUpdateFailedNotify({
title: "管理后台非法刷新数据",
token: data.token,
room: data.room,
content: data.content,
userAgent: userAgent,
ip: ip
})
return
}
socket.emit("manage", {
token: data.token,
socketId: socket.id,
title: manageConfig.title,
content: [{
title: "房间频道",
html: await bussinessManageRoomPage.getRoomPageHtml({
tables: tables,
dbClient: dbClient,
sockets: io.sockets,
day: data.content,
})
}, {
title: "数据传输",
html: await bussinessManageDataPage.getDataPageHtml({
tables: tables,
dbClient: dbClient,
sockets: io.sockets,
day: data.content,
})
}, {
title: "其他设置",
html: await bussinessManageSettingPage.getSettingPageHtml({
tables: tables,
rname: data.room,
sid: socket.id,
ip: ip,
device: userAgent
})
}]
})
bussinessNotify.sendManageUpdateInfoNotify({
title: "管理后台重新获取配置",
token: data.token,
room: data.room,
content: JSON.stringify(data.content),
userAgent: userAgent,
ip: ip
})
} catch (e) {
console.log(e)
rtcMessage.message(io, socket, tables, dbClient, {
room: data.room,
emitType: "tips",
to: socket.id,
msg: "系统错误"
})
}
}
module.exports = {
reload
}

View File

@@ -0,0 +1,201 @@
const bussinessDog = require("./../../bussiness/dog/dog")
const bussinessNotify = require("./../../bussiness/notify/notifySocketEvent")
const utils = require("./../../utils/utils");
// 通知事件定义
let opName = {
"sendFileInfo": "准备发送文件",
"sendDone": "文件发送完毕",
"sendBugs": "收到问题反馈",
"sendTxt": "发送文本内容",
"startScreen": "开始网页录屏",
"stopScreen": "停止网页录屏",
"startScreenShare": "开始屏幕共享",
"stopScreenShare": "停止屏幕共享",
"startVideoShare": "开始音视频通话",
"stopVideoShare": "停止音视频通话",
"startPasswordRoom": "创建密码房间",
"addCodeFile": "添加取货码文件",
"getCodeFile" : "取件码取件",
"openaiChat" : "ChatGPT聊天"
}
/**
* 公共模板广播消息
* @param {*} io socketio对象
* @param {*} socket 单个socket连接
* @param {*} tables 数据表对象
* @param {*} dbClient sequelize-orm对象
* @param {*} data event参数
* @returns
*/
async function message(io, socket, tables, dbClient, data){
try {
let {emitType, room, from, to} = data;
let {handshake, userAgent, ip} = utils.getSocketClientInfo(socket);
let clientsInRoom = io.sockets.adapter.rooms[room];
//特殊事件
if(emitType === 'commData'){
socket.emit('commData',{
switchData : data.switchData,
chatingCommData : data.chatingCommData
});
return
}
if (clientsInRoom) {
let otherSocketIds = Object.keys(clientsInRoom.sockets);
for (let i = 0; i < otherSocketIds.length; i++) {
let otherSocket = io.sockets.connected[otherSocketIds[i]];
if(to && to === otherSocket.id){ //有指定发送id不用走广播
otherSocket.emit(emitType, data);
return;
}
if(from != otherSocket.id){
otherSocket.emit(emitType, data);
}
}
}
if (emitType === 'sendFileInfo') {
bussinessNotify.sendFileInfoNotify({
title: opName.sendFileInfo,
room: data.room,
recoderId: data.recoderId,
from: data.from,
name: data.name,
type: data.type,
size: data.size,
userAgent: userAgent,
ip: ip
})
}
if (emitType === 'sendDone') {
bussinessNotify.sendFileDoneNotify({
title: opName.sendDone,
room: data.room,
to: data.to,
from: data.from,
name: data.name,
type: data.type,
size: data.size,
userAgent: userAgent,
ip: ip
})
}
if (emitType === 'sendBugs') {
bussinessNotify.sendBugNotify({
title: opName.sendBugs,
room: data.room,
msg: data.msg,
userAgent: userAgent,
ip: ip
})
}
if (emitType === 'sendTxt') {
bussinessNotify.sendTxtNotify({
title: opName.sendTxt,
room: data.room,
from: data.from,
recoderId: data.recoderId,
content: data.content,
userAgent: userAgent,
ip: ip
})
}
if (emitType === 'startScreen') {
bussinessNotify.sendStartScreenNotify({
title: opName.startScreen,
userAgent: userAgent,
ip: ip
})
}
if (emitType === 'stopScreen') {
bussinessNotify.sendStopScreenNotify({
title: opName.stopScreen,
userAgent: data.userAgent,
cost: data.cost,
size: data.size,
userAgent: userAgent,
ip: ip
})
}
if (emitType === 'startScreenShare') {
bussinessNotify.sendStartScreenShareNotify({
title: opName.startScreenShare,
userAgent: userAgent,
ip: ip,
room: data.room
})
}
if (emitType === 'stopScreenShare') {
bussinessNotify.sendStopScreenShareNotify({
title: opName.stopScreenShare,
userAgent: data.userAgent,
cost: data.cost,
userAgent: userAgent,
ip: ip,
room: data.room
})
}
if (emitType === 'startVideoShare') {
bussinessNotify.sendStartVideoShareNotify({
title: opName.startVideoShare,
userAgent: userAgent,
ip: ip,
room: data.room
})
}
if (emitType === 'stopVideoShare') {
bussinessNotify.sendStopVideoShareNotify({
title: opName.stopVideoShare,
userAgent: data.userAgent,
cost: data.cost,
userAgent: userAgent,
ip: ip,
room: data.room
})
}
if (opName[data.emitType]) {
await bussinessDog.dogData({
tables: tables,
name: opName[data.emitType],
roomId: "",
socketId: "",
device: userAgent,
flag: 0,
content: JSON.stringify(data),
handshake: JSON.stringify(handshake),
ip: ip
});
}
} catch (e) {
console.log(e)
socket.emit("tips", {
room: data.room,
emitType: "tips",
to: socket.id,
msg: "系统错误"
});
}
}
module.exports = {
message
}

View File

@@ -0,0 +1,21 @@
/**
* webrtc offer
* 转发offer消息至room其他客户端 [from,to,room,sdp]
* @param {*} io socketio对象
* @param {*} socket 单个socket连接
* @param {*} tables 数据表对象
* @param {*} dbClient sequelize-orm对象
* @param {*} data event参数
* @returns
*/
async function offer(io, socket, tables, dbClient, data){
let otherClient = io.sockets.connected[data.to];
if (!otherClient) {
return;
}
otherClient.emit('offer', data);
}
module.exports = {
offer
}

View File

@@ -0,0 +1,82 @@
const bussinessDog = require("./../../bussiness/dog/dog")
const rtcMessage = require("./../rtcMessage/message");
const bussinessNotify = require("./../../bussiness/notify/notifySocketEvent")
const rtcCommData = require("./../rtcCommData/commData");
const utils = require("./../../utils/utils");
const bussinessOpenai = require("./../../bussiness/openai/openai")
/**
* 公共聊天频道
* @param {*} io socketio对象
* @param {*} socket 单个socket连接
* @param {*} tables 数据表对象
* @param {*} dbClient sequelize-orm对象
* @param {*} data event参数
* @returns
*/
async function openai(io, socket, tables, dbClient, data){
let cacheSwitchData = rtcCommData.getCacheSwitchData()
if(!cacheSwitchData.openAiChat){
rtcMessage.message(io, socket, tables, dbClient, {
room: data.room,
emitType: "tips",
to: socket.id,
msg: "当前功能已暂时关闭,有问题可以加群交流"
})
return
}
let {roomId = "10086", content, value} = data;
if(value){
value = value.substr(0, 1000)
}
// 有上下文,结合上下文
if(content){
content = content.substr(0, 5000);
content += "。\n假定以上的内容是提问者和你的对话结合上面的语境回答下面的问题并且注意如果提问内容或者你的回答内容涉及政治请回复 “我已经被设置关闭涉政问答功能”。提问内容为 : "+value;
}else{
// 没有就默认
content = value;
}
let {handshake, userAgent, ip} = utils.getSocketClientInfo(socket);
data.time = new Date().toLocaleString()
data.type = "openai";
data.content = await bussinessOpenai.openaiChat(content, roomId);
data.value = "";
let to = socket.id;
let otherSocket = io.sockets.connected[to];
if(otherSocket){
otherSocket.emit("openaiAnswer", data);
}
await bussinessDog.dogData({
name: opName.openaiChat,
tables: tables,
roomId: roomId,
socketId: data.socketId,
device: userAgent,
flag: 0,
content: decodeURIComponent(data.content),
handshake: JSON.stringify(handshake),
ip: ip
});
bussinessNotify.sendOpenaiChatNotify({
title: opName.openaiChat,
room: roomId,
keys : JSON.stringify(bussinessOpenai.apiKeysStatus()),
content: content,
answer : message.content,
userAgent: userAgent,
ip: ip
})
}
module.exports = {
openai
}

View File

@@ -1,288 +0,0 @@
/**
* 封装socket连接公共方法
*/
class SocketHandler {
constructor(sockets,socket){
this.sockets = sockets;
this.socket = socket;
}
/**
* 后台修改配置广播
* @param {*} message
* @param {*} params
*/
_commDataChange( message, params){
try{
this.sockets.emit("commData", message)
}catch(e){
console.log(e)
}
}
/**
* 公共聊天频道
* @param {*} message
* @param {*} params
*/
_chatingComm( message, params){
try{
this.sockets.emit("chatingComm", message)
}catch(e){
console.log(e)
}
}
/**
* 数量
* @param {*} message
* @param {*} params
*/
_count( message, params){
try{
let allManCount = Object.keys(this.sockets.connected).length || 0;
this.sockets.emit("count", {
mc : allManCount
})
}catch(e){
console.log(e)
}
}
/**
* 链接断开
* @param {*} message
* @param {*} params
*/
_disconnect(message, params){
let socketId = this.socket.id;
let data = {
from : socketId,
};
this.socket.broadcast.emit('exit',data);
this._count(message, params)
}
/**
* 创建并加入
* @param {*} message
* @param {*} params
*/
_createAndJoin(message, params){
let room = message.room;
let type = message.type;
let nickName = message.nickName;
let password = message.password || '';
if(nickName && nickName.length > 20){
nickName = nickName.substr(0, 20);
}
if(password && password.length > 6){
password = password.toString().substr(0,6);
}
let clientsInRoom = this.sockets.adapter.rooms[room];
let numClients = clientsInRoom ? Object.keys(clientsInRoom.sockets).length : 0;
if (numClients === 0) {
this.socket.join(room);
let createdData = {
id: this.socket.id,
room: room,
nickName : nickName,
peers: [],
type: type
};
Object.assign(createdData,params['created'])
this.socket.emit('created', createdData);
// 首次创建-直接设置密码即可
this.sockets.adapter.rooms[room].password = password
}else {
//流媒体房间只允许两个人同时在线
if((type === 'screen' || type === 'video') && numClients >= 2){
this.socket.emit("tips", {
room : message.room,
to : this.socket.id,
msg : "当前房间已满,请开启其他房间号发起操作"
});
return
}
// 密码不对
let roomPassword = this.sockets.adapter.rooms[room].password;
if(roomPassword !== password){
this.socket.emit("tips", {
room : message.room,
nickName : nickName,
to : this.socket.id,
msg : "密码错误",
reload : true
});
return
}
let joinedData = {
id: this.socket.id,
room: room,
nickName : nickName,
type: type
};
Object.assign(joinedData,params['joined'])
this.sockets.in(room).emit('joined',joinedData);
let peers = new Array();
let otherSocketIds = Object.keys(clientsInRoom.sockets);
for (let i = 0; i < otherSocketIds.length; i++) {
let otherSocketId = otherSocketIds[i]
let peerNickName = this.sockets.connected[otherSocketId].nickName
peers.push({
id: otherSocketId,
nickName: peerNickName
});
}
this.socket.join(room);
let createdData = {
id: this.socket.id,
room: room,
nickName : nickName,
peers: peers,
type: type
};
Object.assign(createdData,params['created'])
this.socket.emit('created', createdData);
}
this._count(message, params)
this.sockets.connected[this.socket.id].nickName = nickName;
}
/**
* 【offer】转发offer消息至room其他客户端 [from,to,room,sdp]
* @param {*} message
* @param {*} params
*/
_offer(message, params){
let otherClient = this.sockets.connected[message.to];
if (!otherClient) {
return;
}
otherClient.emit('offer', message);
}
/**
* 【answer】转发answer消息至room其他客户端 [from,to,room,sdp]
* @param {*} message
* @param {*} params
*/
_answer(message, params){
let otherClient = this.sockets.connected[message.to];
if (!otherClient) {
return;
}
otherClient.emit('answer', message);
}
/**
* 【candidate】转发candidate消息至room其他客户端 [from,to,room,candidate[sdpMid,sdpMLineIndex,sdp]]
* @param {*} message
* @param {*} params
*/
_candidate(message, params){
let otherClient = this.sockets.connected[message.to];
if (!otherClient){
return;
}
otherClient.emit('candidate', message);
}
/**
* 【exit】关闭连接转发exit消息至room其他客户端 [from,room]
* @param {*} message
* @param {*} params
*/
_exit(message, params){
let room = message.room;
this.socket.leave(room);
let clientsInRoom = this.sockets.adapter.rooms[room];
if (clientsInRoom) {
let otherSocketIds = Object.keys(clientsInRoom.sockets);
for (let i = 0; i < otherSocketIds.length; i++) {
let otherSocket = this.sockets.connected[otherSocketIds[i]];
otherSocket.emit('exit', message);
}
}
this._count(message, params)
}
_message(message){
let room = message.room;
let emitType = message.emitType;
let from = message.from;
let to = message.to;
let clientsInRoom = this.sockets.adapter.rooms[room];
//特殊事件
if(emitType === 'commData'){
this.socket.emit('commData',{
switchData : message.switchData,
chatingCommData : message.chatingCommData
});
return
}
if (clientsInRoom) {
let otherSocketIds = Object.keys(clientsInRoom.sockets);
for (let i = 0; i < otherSocketIds.length; i++) {
let otherSocket = this.sockets.connected[otherSocketIds[i]];
if(to && to === otherSocket.id){ //有指定发送id不用走广播
otherSocket.emit(emitType, message);
return;
}
if(from != otherSocket.id){
otherSocket.emit(emitType, message);
}
}
}
}
/**
* 取件码
* @param {*} message
*/
_getCodeFile(message){
let to = this.socket.id;
let otherSocket = this.sockets.connected[to];
if(otherSocket){
otherSocket.emit("getCodeFile", message);
}
}
/**
* ai聊天
* @param {*} message
*/
_openaiChat(message){
let to = this.socket.id;
let otherSocket = this.sockets.connected[to];
if(otherSocket){
otherSocket.emit("openaiAnswer", message);
}
}
}
module.exports = {
SocketHandler : SocketHandler
}

View File

@@ -1,82 +1,51 @@
const Sql = require('sequelize');
const sequelizeObj = require('sequelize');
const fs = require('fs');
let sql = null;
let models = {};
//export outside
function excute(config) {
init(config);
return {
tables : models,
sql : sql,
Sql : Sql
};
}
//main
function init(config) {
if(config.db.beforeInit){
config.db.beforeInit();
}
async function excute(config) {
let dbConf = config.db.mysql;
sql = new Sql(dbConf.dbName, dbConf.user, dbConf.password, dbConf.other.sequelize);
connectDb(sql);
initTable(sql);
syncDb(sql);
if(config.db.afterInit){
config.db.afterInit();
}
}
let dbClient = new sequelizeObj(dbConf.dbName, dbConf.user, dbConf.password, dbConf.other.sequelize);
//connect to db
async function connectDb(sql){
try {
let connect = await sql.authenticate();
console.log('连接成功');
let connect = await dbClient.authenticate();
console.log('db connect ok ... ');
} catch (e) {
console.log('连接失败');
console.log('db connect err ...', e);
}
}
//init table
async function initTable() {
let tables = {}
let files = fs.readdirSync(__dirname);
for (let f of files) {
if (f[0] == '.' || f == 'db.js') continue;
try {
let fn = require('./' + f);
if (typeof fn == 'function') {
let ms = fn(sql, Sql);
let ms = fn(dbClient, sequelizeObj);
for (let k in ms) {
models[k] = ms[k];
tables[k] = ms[k];
}
}
} catch (e) {
console.log(e);
}
}
}
// sync db tables
async function syncDb(sql) {
try{
let res = sql.sync({
try {
let res = await dbClient.sync({
force: false
});
console.log("同步成功");
}catch(e){
console.log("同步失败");
console.log("db sync ok ...");
} catch (e) {
console.log("db sync err : ",e);
}
return {
tables,
dbClient,
};
}
//other init methods ...
module.exports = {
excute

View File

@@ -1,43 +1,43 @@
// dog
module.exports = (sequelize, DataTypes) => {
return {
Dog : sequelize.define('dog', {
id : {
Dog: sequelize.define('dog', {
id: {
type: DataTypes.INTEGER,
comment: '功能id',
primaryKey: true,
autoIncrement : true
autoIncrement: true
},
name : {
name: {
type: DataTypes.STRING(20),
comment: '操作功能名称'
},
room_id : {
room_id: {
type: DataTypes.STRING(25),
comment: '房间号'
},
socket_id : {
socket_id: {
type: DataTypes.STRING(25),
comment: '连接id'
},
device : {
device: {
type: DataTypes.STRING(256),
comment: '设备'
},
flag : {
flag: {
type: DataTypes.INTEGER,
comment: '标志位',
defaultValue: 0,
},
content : {
content: {
type: DataTypes.TEXT,
comment: '详细信息'
},
handshake : {
handshake: {
type: DataTypes.TEXT,
comment: '客户端信息'
}
},{
}, {
timestamps: true,
comment: '功能记录表',
indexes: [{
@@ -48,4 +48,3 @@ module.exports = (sequelize, DataTypes) => {
})
};
}

View File

@@ -1,31 +1,31 @@
// room
module.exports = (sequelize, DataTypes) => {
return {
Room : sequelize.define('room', {
id : {
Room: sequelize.define('room', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement : true,
autoIncrement: true,
unique: true,
comment: '数据id',
},
rcode : {
rcode: {
type: DataTypes.STRING(30),
comment: '房间随机编号'
},
rname : {
rname: {
type: DataTypes.STRING(32),
comment: '房间频道号码'
},
uid : {
uid: {
type: DataTypes.INTEGER,
comment: '属于的用户id, 待定~',
},
uname : {
uname: {
type: DataTypes.STRING(20),
comment: '姓名, 待定~'
},
sid : {
sid: {
type: DataTypes.STRING(30),
comment: '进入房间时的sessionId'
},
@@ -33,37 +33,37 @@ module.exports = (sequelize, DataTypes) => {
type: DataTypes.STRING(6),
comment: '房间密码'
},
status : {
status: {
type: DataTypes.INTEGER,
comment: '房间状态',
defaultValue : 0
defaultValue: 0
},
ip : {
ip: {
type: DataTypes.STRING(32),
comment: 'ip'
},
device : {
device: {
type: DataTypes.STRING(256),
comment: '设备'
},
localtion : {
localtion: {
type: DataTypes.STRING(256),
comment: '地理位置'
},
url : {
url: {
type: DataTypes.STRING(256),
comment: '请求url'
},
flag : {
flag: {
type: DataTypes.INTEGER,
comment: '标志位',
defaultValue: 0,
},
content : {
content: {
type: DataTypes.TEXT,
comment: '详细信息'
}
},{
}, {
timestamps: true,
comment: '房间表',
indexes: [{
@@ -74,4 +74,3 @@ module.exports = (sequelize, DataTypes) => {
})
};
}

View File

@@ -0,0 +1,25 @@
const checkLib = require("./core").trie
function contentFilter(text, replaceChar = '*') {
let filteredText = '';
let currentIndex = 0;
while (currentIndex < text.length) {
const match = checkLib.search(text.slice(currentIndex));
if (match) {
filteredText += replaceChar.repeat(match.length);
currentIndex += match.length;
} else {
filteredText += text[currentIndex];
currentIndex++;
}
}
return filteredText;
}
module.exports = {
contentFilter
}
console.log(contentFilter("草泥马,休息休息,傻逼"))

69
src/utils/check/core.js Normal file
View File

@@ -0,0 +1,69 @@
class TrieNode {
constructor() {
this.children = new Map();
this.isEndOfWord = false;
}
}
class Trie {
constructor() {
this.root = new TrieNode();
}
insert(word) {
let node = this.root;
for (const char of word) {
if (!node.children.has(char)) {
node.children.set(char, new TrieNode());
}
node = node.children.get(char);
}
node.isEndOfWord = true;
}
search(word) {
let node = this.root;
let match = '';
for (const char of word) {
if (node.children.has(char)) {
match += char;
node = node.children.get(char);
if (node.isEndOfWord) {
return match;
}
} else {
break;
}
}
return null;
}
}
// 敏感词库
let sensitiveWords = require("./words")
// 将敏感词库转换为前缀树
let trie = null;
(function buildTrie(){
if(!trie){
trie = new Trie();
for (const word of sensitiveWords) {
trie.insert(word);
}
let mem = process.memoryUsage();
let format = function (bytes) {
return (bytes / 1024 / 1024).toFixed(4) + 'MB';
};
console.log({
heapTotal : format(mem.heapTotal),
heapUsed : format(mem.heapUsed),
rss : format(mem.rss)
});
}
})()
module.exports = {
trie
}

76
src/utils/queue/queue.js Normal file
View File

@@ -0,0 +1,76 @@
class tlQueue{
constructor(options){
let {
max = 500, // 最多处理任务数量
queueThreshold = 2, // 1秒最多并发任务数量超过进入队列
queueRate = 1000, // 队列处理单个任务时间间隔, 单位ms
consumerFunc = ()=>{}, // 消费逻辑 Function
queue = [], // 任务队列
count = 0, // 计数器
queueId = -1, // 消费轮询器id
} = options;
this.options = options;
this.max = max;
this.queueThreshold = queueThreshold;
this.queueRate = queueRate;
this.queue = queue;
this.count = count;
this.consumerFunc = consumerFunc;
this.queueId = queueId;
this.init()
}
/**
* 启动
*/
init(){
this.queueId = setInterval(() => {
if(this.queue.length > 0){
this.consume();
console.log("tl-queue pop : ",this.queue.length)
}
}, this.queueRate);
}
/**
* 推数据
* @param {*} data
*/
produce(data) {
//size <= queueThreshold, 允许一些并发执行
if(this.queue.length <= this.queueThreshold){
this.consume();
return
}
// 队列满
if(this.queue.length > this.max){
console.warn("tl-queue out of size : ",this.queue.length)
return
}
console.warn("tl-queue push : ",this.queue.length)
this.queue.push(data)
}
/**
* 拉数据
*/
consume(){
this.consumerFunc(this.queue.shift(), this.options);
}
/**
* 销毁任务
*/
destroy() {
this.queue = [];
clearInterval(this.queueId);
}
}
module.exports = {
tlQueue
}

141
src/utils/utils.js Normal file
View File

@@ -0,0 +1,141 @@
const os = require('os');
/**
* 获取本机ip
* @returns
*/
function getLocalIP() {
const osType = os.type(); //系统类型
const netInfo = os.networkInterfaces(); //网络信息
let ip = '';
if (osType === 'Windows_NT') {
for (let dev in netInfo) {
//win7的网络信息中显示为本地连接win10显示为以太网
if (dev === '本地连接' || dev === '以太网') {
for (let j = 0; j < netInfo[dev].length; j++) {
if (netInfo[dev][j].family === 'IPv4') {
ip = netInfo[dev][j].address;
break;
}
}
}
}
} else if (osType === 'Linux') {
for (let dev in netInfo) {
let iface = netInfo[dev];
for (let i = 0; i < iface.length; i++) {
let alias = iface[i];
if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal) {
return alias.address;
}
}
}
}
return ip;
}
/**
* 获取请求的ip
* @param {*} request
* @returns
*/
function getClientIP(request) {
let ip = request.headers['x-forwarded-for'] ||
request.ip ||
request.connection.remoteAddress ||
request.socket.remoteAddress ||
request.connection.socket.remoteAddress;
if (ip.split(',').length > 0) {
ip = ip.split(',')[0]
}
ip = ip.substr(ip.lastIndexOf(':') + 1, ip.length);
return ip;
}
/**
* 生成随机数
* @param {*} req
* @returns
*/
function genFlow(req) {
return num = Math.floor(Math.random(100000000) * 100000000 + 1);
}
/**
* 生成随机数
* @param {*} req
* @returns
*/
function genRoom(req) {
return num = Math.floor(Math.random(100000000) * 100000000 + 1);
}
/**
* 格式化时间
* @param {*} time
* @param {*} format
* @returns
*/
function formateDateTime(time, format) {
let o = {
'M+': time.getMonth() + 1, // 月份
'd+': time.getDate(), // 日
'h+': time.getHours(), // 小时
'm+': time.getMinutes(), // 分
's+': time.getSeconds(), // 秒
'q+': Math.floor((time.getMonth() + 3) / 3), // 季度
S: time.getMilliseconds(), // 毫秒
};
if (/(y+)/.test(format)) {
format = format.replace(RegExp.$1, (time.getFullYear() + '').substring(4 - RegExp.$1.length));
}
for (let k in o) {
if (new RegExp('(' + k + ')').test(format)) {
format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ('00' + o[k]).substring(('' + o[k]).length));
}
}
return format;
}
/**
* 获取当前时间下一天
* @param {*} time
* @returns
*/
function getNextDay(time) {
let date = new Date(time);
date.setDate(date.getDate() + 1);
let y = date.getFullYear();
let m = date.getMonth() < 9 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1;
let d = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
return y + "-" + m + "-" + d;
}
/**
* 获取socket中的请求客户端信息
* @param {*} socket
* @returns
*/
function getSocketClientInfo(socket){
let handshake = socket.handshake
let userAgent = handshake.headers['user-agent'].toString().substr(0, 255);
let ip = handshake.headers['x-real-ip'] || handshake.headers['x-forwarded-for'] || handshake.headers['host'];
return {
handshake, userAgent, ip
}
}
module.exports = {
getLocalIP,
getClientIP,
genFlow,
genRoom,
formateDateTime,
getNextDay,
getSocketClientInfo
}