Переработаны роутеры приложения

Переписано APi WebSocket для работы с новыми роутерами
This commit is contained in:
2025-10-03 17:11:31 +03:00
parent d75fb7ec3d
commit 6ec6523d71
54 changed files with 2593 additions and 3749 deletions

240
ws/ws.js
View File

@@ -1,226 +1,50 @@
const WebSocket = require("ws");
const { URL } = require('url');
const sqlite3 = require('sqlite3');
const path = require('path');
const { routeMessage } = require("./routes");
const { auth } = require("./middleware/auth");
const { setupPing } = require("./utils/ping");
require("dotenv").config();
const dbPath = process.env.DATABASE_PATH || '../';
const db = new sqlite3.Database(path.join(dbPath, 'database.sqlite'));
const api_version = '1.1.0';
const port = process.env.WS_PORT || 4001;
const api_version = '1.0.0';
const wss = new WebSocket.Server({
port: port
}, () => console.log(`Server started on port ${port}`));
const wss = new WebSocket.Server({ port: 4004 });
console.log("WebSocket сервер запущен на порту 4004");
wss.on('connection', async (ws, request) => {
const url = new URL(request.url, `http://${request.headers.host}`)
wss.on("connection", async (ws, request) => {
const url = new URL(request.url, `http://${request.headers.host}`);
const params = Object.fromEntries(url.searchParams.entries());
const uuid = params.uuid;
const uuid = params.uuid ?? ws.protocol;
if (!uuid) return
if (!uuid) return ws.close();
let check = await checkUUID(uuid);
const user = await auth(uuid);
if (!user) return ws.close();
console.log(check);
try {
const user = await auth(uuid);
if (!user) return ws.close();
ws.user = user;
ws.send(JSON.stringify({ connection: "success", api_version, user: {name: ws.user.name, id: ws.user.id } }));
if (!check && check.possibilities.can_view_territory) return
// Periodic ping to maintain a connection
setupPing(ws);
// Periodic ping to maintain a connection
const pingInterval = setInterval(() => {
if (ws.readyState === WebSocket.OPEN) {
ws.ping('ping');
}
}, 30000);
ws.send(JSON.stringify({ "connection": "success", "api_version": api_version }));
ws.on('message', (message) => {
message = JSON.parse(message);
console.log(message.username, check.name);
switch (message.event) {
case "connection":
broadcastMessage(message);
break;
case "message":
updateDatabase(message);
broadcastMessage(message);
break;
};
});
ws.on('pong', (data) => {
console.log('PONG received from the client:', data.toString());
});
ws.on('close', () => {
console.log('Client close');
});
ws.on('error', (err) => {
console.error('ERROR WebSocket:', err);
});
});
function broadcastMessage(message) {
wss.clients.forEach(client => {
if (client.readyState === WebSocket.OPEN) {
client.send(JSON.stringify(message));
}
});
}
function updateDatabase(message) {
console.log(message.type);
if (message.type === "apartment") {
let sql = 'UPDATE apartments SET status = ?, description = ?, sheep_id = ?, updated_at = ? WHERE id = ?';
db.run(sql, [
Number(message.data.status),
message.data.description,
message.data.sheep_id,
message.data.updated_at,
message.data.id
], function (err) {
if (err) {
console.error(err.message);
} else if (this.changes === 0) {
console.error('Product not found');
} else {
console.log({ "update": "ok", "id": message.data.id });
let sql = `INSERT INTO apartments_history (apartments_id, status, description, sheep_id, created_at) VALUES (?, ?, ?, ?, ?)`;
db.run(sql, [
Number(message.data.id),
Number(message.data.status),
message.data.description,
message.data.sheep_id,
Math.floor(Date.now())
], function (err) {
if (err) {
console.error(err.message);
} else if (this.changes === 0) {
console.error('Apartments not found');
} else {
console.log({ "insert": "ok", "id": this.lastID });
}
});
ws.on("message", (raw) => {
try {
const message = JSON.parse(raw);
routeMessage(wss, ws, message);
} catch (e) {
console.error("❌ Invalid message:", raw);
ws.send(JSON.stringify({ error: "Invalid message format" }));
}
});
} else if(message.type === "building") {
let sql = 'UPDATE buildings SET status = ?, description = ?, sheep_id = ?, updated_at = ? WHERE id = ?';
db.run(sql, [
Number(message.data.status),
message.data.description,
message.data.sheep_id,
message.data.updated_at,
message.data.id
], function (err) {
if (err) {
console.error(err.message);
} else if (this.changes === 0) {
console.error('Product not found');
} else {
console.log({ "update": "ok", "id": message.data.id });
let sql = `INSERT INTO buildings_history (buildings_id, status, description, sheep_id, created_at) VALUES (?, ?, ?, ?, ?)`;
db.run(sql, [
Number(message.data.id),
Number(message.data.status),
message.data.description,
message.data.sheep_id,
Math.floor(Date.now())
], function (err) {
if (err) {
console.error(err.message);
} else if (this.changes === 0) {
console.error('Apartments not found');
} else {
console.log({ "insert": "ok", "id": this.lastID });
}
});
}
});
ws.on("close", () => console.log("🔌 Client disconnected"));
ws.on("error", (err) => console.error("❌ WS error:", err));
} catch (err) {
console.error("❌ Auth error:", err);
ws.close();
}
}
async function checkUUID(uuid) {
return new Promise((res, rej) => {
db.get(`
SELECT
sheeps.*,
possibilities.can_view_territory AS can_view_territory
FROM
sheeps
LEFT JOIN
possibilities ON possibilities.sheep_id = sheeps.id
WHERE
sheeps.uuid_manager = ?`,
[uuid],
(err, moderator) => {
if (moderator) {
let data = {
id: moderator.sheep_id,
group_id: moderator.group_id,
name: moderator.name,
icon: moderator.icon,
uuid: moderator.uuid,
appointment: moderator.appointment,
sheepRole: moderator.mode_title,
possibilities: {
can_view_territory: moderator.can_view_territory == 1 ? true : false
}
}
return res(data);
}
db.get(`
SELECT
sheeps.*,
possibilities.can_view_territory AS can_view_territory
FROM
sheeps
LEFT JOIN
possibilities ON possibilities.sheep_id = sheeps.id
WHERE
sheeps.uuid = ?`,
[uuid],
(err, sheep) => {
if (sheep) {
let data = {
id: sheep.sheep_id,
group_id: sheep.group_id,
name: sheep.name,
icon: sheep.icon,
uuid: sheep.uuid,
appointment: sheep.appointment,
sheepRole: sheep.mode_title,
possibilities: {
can_view_territory: sheep.can_view_territory == 1 ? true : false
}
}
return res(data);
}
return res(false);
}
);
}
);
});
}
});