添加心跳包检测

This commit is contained in:
539943419 committed 2024-03-22 16:38:33 +08:00
1 parent 127f58bd36
commit ec5fcf1ee7
5 files changed
+140 -58

No files matched your search

+15
View File
@@ -15,10 +15,12 @@
"js-base64": "^3.7.6", "js-base64": "^3.7.6",
"pinia": "^2.1.7", "pinia": "^2.1.7",
"sm-crypto": "^0.3.13", "sm-crypto": "^0.3.13",
"uuid": "^9.0.1",
"vicons": "^0.0.1", "vicons": "^0.0.1",
"vue": "^3.4.15", "vue": "^3.4.15",
"vue-clipboard3": "^2.0.0", "vue-clipboard3": "^2.0.0",
"vue-router": "^4.2.5", "vue-router": "^4.2.5",
"websocket-heartbeat-js": "^1.1.3",
"ws": "^8.16.0" "ws": "^8.16.0"
}, },
"devDependencies": { "devDependencies": {
@@ -2359,6 +2361,14 @@
"node": ">= 0.4.0" "node": ">= 0.4.0"
} }
}, },
"node_modules/uuid": {
"version": "9.0.1",
"resolved": "https://registry.npmmirror.com/uuid/-/uuid-9.0.1.tgz",
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
"bin": {
"uuid": "dist/bin/uuid"
}
},
"node_modules/vary": { "node_modules/vary": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmmirror.com/vary/-/vary-1.1.2.tgz", "resolved": "https://registry.npmmirror.com/vary/-/vary-1.1.2.tgz",
@@ -2514,6 +2524,11 @@
"vue": "^3.0.11" "vue": "^3.0.11"
} }
}, },
"node_modules/websocket-heartbeat-js": {
"version": "1.1.3",
"resolved": "https://registry.npmmirror.com/websocket-heartbeat-js/-/websocket-heartbeat-js-1.1.3.tgz",
"integrity": "sha512-wiCMVsWK7KflVCC5f+rSTyzILDZX88A7BJfdJXt5THNDut7uUNP83r5AvdZ1El/8yOwGujC7K3iuxj96CT4gbQ=="
},
"node_modules/wrap-ansi": { "node_modules/wrap-ansi": {
"version": "7.0.0", "version": "7.0.0",
"resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+3
View File
@@ -4,6 +4,7 @@
"private": true, "private": true,
"type": "module", "type": "module",
"scripts": { "scripts": {
"vite": "vite",
"dev": "concurrently \"node server.js\" \"vite\"", "dev": "concurrently \"node server.js\" \"vite\"",
"server": "concurrently \"node server.js\"", "server": "concurrently \"node server.js\"",
"miaoShare": "concurrently \"node server.js\" \"vite\"", "miaoShare": "concurrently \"node server.js\" \"vite\"",
@@ -18,10 +19,12 @@
"js-base64": "^3.7.6", "js-base64": "^3.7.6",
"pinia": "^2.1.7", "pinia": "^2.1.7",
"sm-crypto": "^0.3.13", "sm-crypto": "^0.3.13",
"uuid": "^9.0.1",
"vicons": "^0.0.1", "vicons": "^0.0.1",
"vue": "^3.4.15", "vue": "^3.4.15",
"vue-clipboard3": "^2.0.0", "vue-clipboard3": "^2.0.0",
"vue-router": "^4.2.5", "vue-router": "^4.2.5",
"websocket-heartbeat-js": "^1.1.3",
"ws": "^8.16.0" "ws": "^8.16.0"
}, },
"devDependencies": { "devDependencies": {
+64 -40
View File
@@ -4,6 +4,7 @@ import Database from "better-sqlite3";
import fs from "fs"; import fs from "fs";
import { WebSocketServer } from "ws"; import { WebSocketServer } from "ws";
import http from "http"; import http from "http";
import { v4 as uuid4 } from "uuid";
// import Config from "./miaoShareConfig.json" // import Config from "./miaoShareConfig.json"
const HOST = "0.0.0.0"; const HOST = "0.0.0.0";
@@ -232,19 +233,20 @@ const groupsMap = {};
// 三天不活跃的群组将被清除 // 三天不活跃的群组将被清除
const LifeOfGroup = millisecondsOfOneDay * 3; const LifeOfGroup = millisecondsOfOneDay * 3;
// const LifeOfGroup = 0; // const LifeOfGroup = 0;
// 根据uuid查询加入的群组
const uuid2Groups={}
db.exec( db.exec(
`CREATE TABLE IF NOT EXISTS GROUPS ( `CREATE TABLE IF NOT EXISTS GROUPS (
gID CHAR(8) PRIMARY KEY UNIQUE NOT NULL, gID CHAR(8) PRIMARY KEY UNIQUE NOT NULL,
verify TEXT NOT NULL, verify TEXT NOT NULL,
activeTimestamp INT NOT NULL activeTimestamp INT NOT NULL
);`) );`
);
const stmt_getExpiredGroups = db.prepare(`SELECT gID FROM GROUPS WHERE activeTimestamp < ? `); const stmt_getExpiredGroups = db.prepare(`SELECT gID FROM GROUPS WHERE activeTimestamp < ? `);
const stmt_getGroupVerify = db.prepare(`SELECT verify FROM GROUPS WHERE gID = ? `) const stmt_getGroupVerify = db.prepare(`SELECT verify FROM GROUPS WHERE gID = ? `);
const stmt_insertGROUPS = db.prepare(`INSERT INTO GROUPS (gID,verify, activeTimestamp) VALUES (?, ?, ?)`); const stmt_insertGROUPS = db.prepare(`INSERT INTO GROUPS (gID,verify, activeTimestamp) VALUES (?, ?, ?)`);
@@ -252,25 +254,24 @@ const stmt_updateGROUPS_ActiveTimestamp = db.prepare(`UPDATE GROUPS SET activeTi
const stmt_deleteGroup = db.prepare(`DELETE FROM GROUPS WHERE gID=?`); const stmt_deleteGroup = db.prepare(`DELETE FROM GROUPS WHERE gID=?`);
const generateStmt_insertMessage_map = {} const generateStmt_insertMessage_map = {};
const updateGROUPS = () => { const updateGROUPS = () => {
// console.log(1) // console.log(1)
try { try {
let gIDs = stmt_getExpiredGroups.all(parseInt(Date.now()) - LifeOfGroup); let gIDs = stmt_getExpiredGroups.all(parseInt(Date.now()) - LifeOfGroup);
for (let row of gIDs) { for (let row of gIDs) {
let gID = row.gID let gID = row.gID;
db.exec(`DROP TABLE IF EXISTS ${gID}`) db.exec(`DROP TABLE IF EXISTS ${gID}`);
stmt_deleteGroup.run(gID) stmt_deleteGroup.run(gID);
} }
} catch (e) { } catch (e) {
console.log(e); console.log(e);
return; return;
} }
}; };
updateGROUPS() updateGROUPS();
setInterval(updateGROUPS,1000*3600*3) setInterval(updateGROUPS, 1000 * 3600 * 3);
// 创建群组的数据库 // 创建群组的数据库
function createGroupTableDB(gID, verify) { function createGroupTableDB(gID, verify) {
@@ -280,70 +281,86 @@ function createGroupTableDB(gID,verify){
type TEXT NOT NULL, type TEXT NOT NULL,
sender TEXT NOT NULL, sender TEXT NOT NULL,
timestamp INT NOT NULL timestamp INT NOT NULL
);`) );`
stmt_insertGROUPS.run(gID,verify,parseInt(Date.now())) );
stmt_insertGROUPS.run(gID, verify, parseInt(Date.now()));
} }
// 插入信息 // 插入信息
function insertMessageByGID(gID,msg,sender){ function insertMessageByGID(gID, msg, from) {
if (!generateStmt_insertMessage_map[gID]) { if (!generateStmt_insertMessage_map[gID]) {
generateStmt_insertMessage_map[gID] = db.prepare(`INSERT INTO ${gID} (message,type,sender, timestamp) VALUES (?, ?, ?, ?)`); generateStmt_insertMessage_map[gID] = db.prepare(`INSERT INTO ${gID} (message,type,sender, timestamp) VALUES (?, ?, ?, ?)`);
} }
generateStmt_insertMessage_map[gID].run(msg,'gMsg',sender,parseInt(Date.now())) generateStmt_insertMessage_map[gID].run(msg, "gMsg", from, parseInt(Date.now()));
} }
function updateActiveTimestamp(gID) { function updateActiveTimestamp(gID) {
stmt_updateGROUPS_ActiveTimestamp.run(parseInt(Date.now()),gID) stmt_updateGROUPS_ActiveTimestamp.run(parseInt(Date.now()), gID);
} }
function createGroup(verify) { function createGroup(verify) {
// 暂时不考虑id随机生成时重复的问题 // 暂时不考虑id随机生成时重复的问题
let gID = generateId(true); let gID = generateId(true);
groupsMap[gID] = { verify, member: [], msgHistory: [] }; groupsMap[gID] = { verify, member: [], msgHistory: [] };
createGroupTableDB(gID,verify) createGroupTableDB(gID, verify);
return gID; return gID;
} }
function getGroupVerify(gID) { function getGroupVerify(gID) {
if(!groupsMap[gID]){ initMsgHistory(gID)
let verify = stmt_getGroupVerify.get(gID).verify
// 暂时这么写
let msgHistory = db.prepare(`SELECT message,type FROM ${gID}`).all().map(v=>{
return {msg: v.message,type:v.type}
})
// console.log(msgHistory)
groupsMap[gID] = { verify, member: [], msgHistory};
}
return groupsMap[gID].verify; return groupsMap[gID].verify;
} }
// 正式加入群组 // 正式加入群组
function joinGroup(socket, gID, callback) { function joinGroup(socket, gID, callback) {
initMsgHistory(gID)
groupsMap[gID].member.push(socket); groupsMap[gID].member.push(socket);
updateActiveTimestamp(gID) updateActiveTimestamp(gID);
callback(); callback();
} }
// 暂时这么写 // 暂时这么写
function getHistory(gID) { function getHistory(gID) {
initMsgHistory(gID)
return groupsMap[gID].msgHistory; return groupsMap[gID].msgHistory;
} }
function broadcastMsg(gID, msg) { function broadcastMsg(gID, msg, from) {
updateActiveTimestamp(gID) initMsgHistory(gID)
insertMessageByGID(gID,msg,'NULL') updateActiveTimestamp(gID);
insertMessageByGID(gID, msg, from);
let bmsg = JSON.stringify({ type: "gMsg", gID, msg }) let bmsg = JSON.stringify({ type: "gMsg", gID, msg });
groupsMap[gID].msgHistory.push({ type: "gMsg", msg }); groupsMap[gID].msgHistory.push({ type: "gMsg", msg, from });
for (let socket of groupsMap[gID].member) { for (let socket of groupsMap[gID].member) {
socket.send(bmsg); socket.send(bmsg);
} }
} }
function initMsgHistory(gID){
if (!groupsMap[gID]) {
let verify = stmt_getGroupVerify.get(gID).verify;
// 暂时这么写
let msgHistory = db
.prepare(`SELECT message,type FROM ${gID}`)
.all()
.map(v => {
return { msg: v.message, type: v.type };
});
// console.log(msgHistory)
groupsMap[gID] = { verify, member: [], msgHistory };
}
}
// 灵车
wss.on("connection", socket => { wss.on("connection", socket => {
console.log("新的连接已建立"); console.log("新的连接已建立");
const no = wss.clients.size; const no = wss.clients.size;
const joinedGroup = [] const joinedGroup = [];
var uuid = uuid4();
function setUuid(new_uuid){
uuid = new_uuid
}
socket.on("message", message => { socket.on("message", message => {
try { try {
console.log(message.toString()); console.log(message.toString());
@@ -358,37 +375,44 @@ wss.on("connection", socket => {
if (msg.type1 === "verify") { if (msg.type1 === "verify") {
// 已经加入则return // 已经加入则return
if (joinedGroup.includes(msg.gID)) { if (joinedGroup.includes(msg.gID)) {
return return;
} }
socket.send(JSON.stringify({ type: "sMsg", type1: "joinVerify", verify: getGroupVerify(msg.gID), gID: msg.gID })); socket.send(JSON.stringify({ type: "sMsg", type1: "joinVerify", verify: getGroupVerify(msg.gID), gID: msg.gID }));
} else if (msg.type1 === "success") { } else if (msg.type1 === "success") {
if (joinedGroup.includes(msg.gID)) { if (joinedGroup.includes(msg.gID)) {
return return;
} }
// 成功加入 // 成功加入
joinGroup(socket, msg.gID, () => { joinGroup(socket, msg.gID, () => {
joinedGroup.push(msg.gID) joinedGroup.push(msg.gID);
// 不考虑失败属于是 // 不考虑失败属于是
socket.send(JSON.stringify({ type: "sMsg", gID: msg.gID, type1: "history", history: JSON.stringify(getHistory(msg.gID)) })); socket.send(JSON.stringify({ type: "sMsg", gID: msg.gID, type1: "history", history: JSON.stringify(getHistory(msg.gID)) }));
}); });
} }
} else if (type === "message") { } else if (type === "message") {
let gID = msg.gID; let gID = msg.gID;
broadcastMsg(gID, msg.msg); broadcastMsg(gID, msg.msg,uuid);
} else if (type === "heartbeat") {
socket.send(JSON.stringify({ type: "sMsg", type1: "heartbeat" }));
} else if (type === "uuid") {
if (msg.type1 === "get") {
socket.send(JSON.stringify({ type: "sMsg", type1: "uuid", uuid }));
} else if (msg.type1 === "set") {
uuid = msg.uuid
}
} }
} }
} catch (e) { } catch (e) {
console.log(e); console.log(e);
} }
}); });
socket.on("close", () => { socket.on("close", () => {
for (let gID of joinedGroup) { for (let gID of joinedGroup) {
groupsMap[gID].member = groupsMap[gID].member.filter(v=>v!==socket) groupsMap[gID].member = groupsMap[gID].member.filter(v => v !== socket);
} }
console.log(`No.${no} exit.`); console.log(`No.${no} exit.`);
console.log(groupsMap) console.log(groupsMap);
}); });
}); });
+12 -4
View File
@@ -61,12 +61,16 @@ const SM4 = (key,data)=>{
return new Uint8Array(encryptedBytes); return new Uint8Array(encryptedBytes);
} }
const encrypt = (key, data, fileName, setting, message) => { const encrypt = (key, data, fileName, setting, message) => {
// if(!encryptFunction){
// encryptFunction = setting.activeFuction
// }
let encryptFunction = {0:'不加密',16:'AES128',19:'SM4',32:'AES256'}[key.length]
return blob2Uint8Array(data).then(data => { return blob2Uint8Array(data).then(data => {
let encrypted_data = null let encrypted_data = null
if(setting.activeFuction === "不加密"){ if(encryptFunction === "不加密"|| key === ''){
encrypted_data = data encrypted_data = data
// AES // AES
}else if(setting.activeFuction != "SM4"){ }else if(encryptFunction != "SM4"){
message.info(`开始加密${fileName}`); message.info(`开始加密${fileName}`);
encrypted_data = AES(key,data) encrypted_data = AES(key,data)
message.info(`${fileName}加密完成`); message.info(`${fileName}加密完成`);
@@ -83,11 +87,15 @@ const encrypt = (key, data, fileName, setting, message) => {
// setting为pinia存储的setting。。。 // setting为pinia存储的setting。。。
const encryptString = (key, str, setting) => { const encryptString = (key, str, setting) => {
// if(!encryptFunction){
// encryptFunction = setting.activeFuction
// }
// console.log(key,key.length) // console.log(key,key.length)
if(setting.activeFuction === "不加密" || key === ''){ let encryptFunction = {0:'不加密',16:'AES128',19:'SM4',32:'AES256'}[key.length]
if(encryptFunction === "不加密" || key === ''){
// return sm4.encrypt(str, 'miaospringmiaospringmiaospringao') // return sm4.encrypt(str, 'miaospringmiaospringmiaospringao')
return Base64.encode(str) return Base64.encode(str)
}else if(setting.activeFuction !== "SM4"){ }else if(encryptFunction !== "SM4"){
key = aesjs.utils.utf8.toBytes(key); key = aesjs.utils.utf8.toBytes(key);
var data = aesjs.utils.utf8.toBytes(str); var data = aesjs.utils.utf8.toBytes(str);
var aesCtr = new aesjs.ModeOfOperation.ctr(key, new aesjs.Counter(5)); var aesCtr = new aesjs.ModeOfOperation.ctr(key, new aesjs.Counter(5));
+46 -14
View File
@@ -38,6 +38,7 @@ import {NText,NDataTable,NButton,NInput} from 'naive-ui'
import { useSettingStore } from "@/pinia/store"; import { useSettingStore } from "@/pinia/store";
import { generateKey,encryptString } from '@/func/upload'; import { generateKey,encryptString } from '@/func/upload';
import { decryptString } from '@/func/download'; import { decryptString } from '@/func/download';
import WebsocketHeartbeatJs from 'websocket-heartbeat-js';
@@ -61,18 +62,26 @@ const codeInput = ref('')
const key = ref('') const key = ref('')
const msg = ref('') const msg = ref('')
const joinedGroup = [] const joinedGroup = []
const uuid = ref('')
const gID2key = {} const gID2key = {}
const options = {
url: baseUrl,
pingTimeout: 20000,
pongTimeout: 10000,
reconnectTimeout: 3000,
pingMsg: JSON.stringify({type:'heartbeat'})
}
let socket = new WebsocketHeartbeatJs(options);
// const socket = new WebSocket(baseUrl);
// socket.addEventListener("open", (event) => {
// // socket.send("");
// });
const socket = new WebSocket(baseUrl); socket.onmessage= (event) => {
socket.addEventListener("open", (event) => {
// socket.send("");
});
socket.addEventListener("message", (event) => {
const msg = JSON.parse(event.data) const msg = JSON.parse(event.data)
data.value.push({from:'server',msg:event.data}) data.value.push({from:'server',msg:event.data})
if(msg.type){ if(msg.type){
@@ -83,8 +92,8 @@ socket.addEventListener("message", (event) => {
gID.value=msg.gID gID.value=msg.gID
}else if(type1 === 'joinVerify'){ }else if(type1 === 'joinVerify'){
let gID = msg.gID let gID = msg.gID
let key = gID2key[gID] let key = gID2key[gID].key
console.log(gID2key,gID,key) // console.log(gID2key,gID,key)
let res = decryptString(key,msg.verify) let res = decryptString(key,msg.verify)
console.log(res,key,msg.verify) console.log(res,key,msg.verify)
if(res === 'miaoSpring'){ if(res === 'miaoSpring'){
@@ -93,18 +102,40 @@ socket.addEventListener("message", (event) => {
} }
}else if(type1 === 'history'){ }else if(type1 === 'history'){
let gID = msg.gID let gID = msg.gID
let key = gID2key[gID] let key = gID2key[gID].key
for(let m of JSON.parse(msg.history)){ for(let m of JSON.parse(msg.history)){
data.value.push({from:'decrypt',msg:decryptString(key,m.msg)}) data.value.push({from:'decrypt',msg:decryptString(key,m.msg)})
} }
}else if(type1 === 'uuid'){
uuid.value = msg.uuid
} }
}else if(type === 'gMsg'){ }else if(type === 'gMsg'){
let gID = msg.gID let gID = msg.gID
let key = gID2key[gID] let key = gID2key[gID].key
data.value.push({from:'decrypt',msg:decryptString(key,msg.msg)}) data.value.push({from:'decrypt',msg:decryptString(key,msg.msg)})
} }
} }
}); };
socket.onopen = ()=>{
if(uuid.value){
socket.send(JSON.stringify({type:'uuid',type1:'set',uuid:uuid.value}))
}else{
socket.send(JSON.stringify({type:'uuid',type1:'get'}))
}
console.log(joinedGroup)
let toJoin = [...joinedGroup]
joinedGroup.length = 0
for(let gID of toJoin){
let code = gID+gID2key[gID].key
console.log(code)
joinGroup(code)
}
}
socket.onreconnect = (e) => {
console.log('reconnecting...');
}
function createGroup(){ function createGroup(){
let keyt = generateKey(setting) let keyt = generateKey(setting)
@@ -118,7 +149,8 @@ function joinGroup(code){
if(joinedGroup.includes(gID)){ if(joinedGroup.includes(gID)){
return return
} }
gID2key[gID] = key gID2key[gID] = {}
gID2key[gID].key = key
joinGroup_Verify(gID) joinGroup_Verify(gID)
} }
@@ -127,7 +159,7 @@ function joinGroup_Verify(gID){
} }
function sendMsg(gID,msg){ function sendMsg(gID,msg){
let key = gID2key[gID] let key = gID2key[gID].key
msg = encryptString(key,msg,setting) msg = encryptString(key,msg,setting)
socket.send(JSON.stringify({type:'message',msg,gID})) socket.send(JSON.stringify({type:'message',msg,gID}))
} }