Sockets funcionais

This commit is contained in:
JotaChina committed 2025-11-04 16:33:21 -03:00
1 parent 97c0daf697
commit d38cd9e60f
4 files changed
+86 -18

No files matched your search

+2
View File
@@ -14,3 +14,5 @@ export const PIXELS_PER_BAR = 512; // 16 steps * 32px/step = 512px por compasso
// Níveis de zoom pré-definidos (fator de multiplicação) // Níveis de zoom pré-definidos (fator de multiplicação)
export const ZOOM_LEVELS = [0.25, 0.5, 1.0, 2.0, 4.0, 8.0]; export const ZOOM_LEVELS = [0.25, 0.5, 1.0, 2.0, 4.0, 8.0];
export const PORT_SOCK = 33001;
+50 -1
View File
@@ -61,7 +61,6 @@ export async function loadProjectFromServer(fileName) {
} }
} }
// --- NENHUMA MUDANÇA DAQUI PARA BAIXO ---
// 'parseMmpContent' agora é chamado pelo 'socket.js' // 'parseMmpContent' agora é chamado pelo 'socket.js'
// quando ele recebe a ação 'LOAD_PROJECT' ou 'load_project_state'. // quando ele recebe a ação 'LOAD_PROJECT' ou 'load_project_state'.
@@ -244,6 +243,56 @@ export function generateMmpFile() {
} }
} }
// Função auxiliar (pode ser movida para cá) que gera o XML a partir do appState
// Copiada de generateMmpFile/modifyAndSaveExistingMmp
function generateXmlFromState() {
if (!appState.global.originalXmlDoc) {
// Se não houver XML original, precisamos gerar um novo
// Por simplicidade, para este fix, vamos retornar o estado atual do LMMS
// mas o ideal seria gerar o XML completo (como generateNewMmp)
console.warn("Não há XML original para modificar. Usando a base atual do appState.");
// No seu caso, use o conteúdo de generateNewMmp()
return "";
}
const xmlDoc = appState.global.originalXmlDoc.cloneNode(true);
const head = xmlDoc.querySelector("head");
if (head) {
head.setAttribute("bpm", document.getElementById("bpm-input").value);
head.setAttribute("num_bars", document.getElementById("bars-input").value);
head.setAttribute("timesig_numerator", document.getElementById("compasso-a-input").value);
head.setAttribute("timesig_denominator", document.getElementById("compasso-b-input").value);
}
const bbTrackContainer = xmlDoc.querySelector('track[type="1"] > bbtrack > trackcontainer');
if (bbTrackContainer) {
bbTrackContainer.querySelectorAll('track[type="0"]').forEach(node => node.remove());
const tracksXml = appState.pattern.tracks.map((track) => createTrackXml(track)).join("");
const tempDoc = new DOMParser().parseFromString(`<root>${tracksXml}</root>`, "application/xml");
Array.from(tempDoc.documentElement.children).forEach((newTrackNode) => {
bbTrackContainer.appendChild(newTrackNode);
});
}
const serializer = new XMLSerializer();
return serializer.serializeToString(xmlDoc);
}
/**
* Envia o estado ATUAL do projeto (XML dos padrões) para o servidor
* para que ele persista a "cópia temporária" em disco/memória.
* Deve ser chamado APÓS alterações significativas no padrão (steps, tracks).
*/
export function syncPatternStateToServer() {
if (!window.ROOM_NAME) return; // Não faz nada se não estiver em sala
const currentXml = generateXmlFromState();
// NOTA: Usamos um novo tipo de ação para não confundir com o carregamento de arquivo
sendAction({
type: 'SYNC_PATTERN_STATE',
xml: currentXml
});
}
function createTrackXml(track) { function createTrackXml(track) {
if (track.patterns.length === 0) return ""; if (track.patterns.length === 0) return "";
const ticksPerStep = 12; const ticksPerStep = 12;
+31 -15
View File
@@ -1,14 +1,15 @@
// server.js - VERSÃO 6 (ACK + Clock Sync + Logs Dinâmicos + Persistência Autoritativa) // server.js - VERSÃO 6 (ACK + Clock Sync + Logs Dinâmicos + Persistência Autoritativa) - HTTPS ENABLED
// ========================= // =========================
// IMPORTS PRINCIPAIS // IMPORTS PRINCIPAIS
// ========================= // =========================
const express = require("express"); const express = require("express");
const { createServer } = require("http"); const https = require("https");
const { Server } = require("socket.io"); const { Server } = require("socket.io");
const fs = require("fs"); const fs = require("fs");
const path = require("path"); const path = require("path");
const pino = require("pino"); const pino = require("pino");
//const { PORT_SOCK } = require("../config.js");
// ------------------------- // -------------------------
// LOGGER DINÂMICO (GERENCIADOR) // LOGGER DINÂMICO (GERENCIADOR)
@@ -57,11 +58,29 @@ function getActionLoggerForRoom(roomName) {
} }
// ------------------------- // -------------------------
// Configuração do Servidor // Configuração do Servidor (HTTPS)
// ------------------------- // -------------------------
const app = express(); const app = express();
const httpServer = createServer(app); const PORT = process.env.PORT || 33001;
const PORT = process.env.PORT || 33007;
// ====== HTTPS (Opção B) ======
const CERT_FULLCHAIN = process.env.SSL_FULLCHAIN || "/etc/letsencrypt/live/alice.ufsj.edu.br/fullchain.pem";
const CERT_PRIVKEY = process.env.SSL_PRIVKEY || "/etc/letsencrypt/live/alice.ufsj.edu.br/privkey.pem";
if (!fs.existsSync(CERT_FULLCHAIN) || !fs.existsSync(CERT_PRIVKEY)) {
console.error("[HTTPS] Certificados não encontrados.\n" +
` fullchain: ${CERT_FULLCHAIN}\n` +
` privkey : ${CERT_PRIVKEY}\n` +
"Defina SSL_FULLCHAIN/SSL_PRIVKEY ou instale os certificados no caminho padrão.");
process.exit(1);
}
const httpsOptions = {
cert: fs.readFileSync(CERT_FULLCHAIN),
key : fs.readFileSync(CERT_PRIVKEY),
};
const httpsServer = https.createServer(httpsOptions, app);
// ------------------------- // -------------------------
// Persistência por sala // Persistência por sala
@@ -128,15 +147,11 @@ function saveRoom(roomName) {
// ------------------------- // -------------------------
// Server / IO // Server / IO
// ------------------------- // -------------------------
const io = new Server(httpServer, { const io = new Server(httpsServer, {
cors: { cors: {
origin: [ // CORREÇÃO: Simplificado para a origem real do cliente, que é onde o HTML é servido.
"https://alice.ufsj.edu.br", // O cliente provavelmente é servido a partir de https://alice.ufsj.edu.br (porta 443).
"http://127.0.0.1:33007", origin: "https://alice.ufsj.edu.br",
"http://localhost:33007",
"http://localhost:5173",
"http://127.0.0.1:5173",
],
methods: ["GET", "POST"], methods: ["GET", "POST"],
credentials: true, credentials: true,
}, },
@@ -509,6 +524,7 @@ app.get("/", (req, res) => {
); );
}); });
httpServer.listen(PORT, () => { // ====== START ======
console.log(`Servidor escutando na porta http://localhost:${PORT}`); httpsServer.listen(PORT, () => {
console.log(`Servidor escutando na porta https://localhost:${PORT}`);
}); });
+3 -2
View File
@@ -1,6 +1,6 @@
// js/socket.js — V5.5 (Toast para Sync Mode) // js/socket.js — V5.5 (Toast para Sync Mode)
// ----------------------------------------------------------------------------- // -------------------relómm------------------------------------------------------
// IMPORTS & STATE // IMPORTS & STATE
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
import { appState, resetProjectState } from "./state.js"; import { appState, resetProjectState } from "./state.js";
@@ -36,6 +36,7 @@ import {
import { parseMmpContent } from "./file.js"; import { parseMmpContent } from "./file.js";
import { renderAll, showToast } from "./ui.js"; // showToast() import { renderAll, showToast } from "./ui.js"; // showToast()
import { updateStepUI, renderPatternEditor } from "./pattern/pattern_ui.js"; import { updateStepUI, renderPatternEditor } from "./pattern/pattern_ui.js";
import { PORT_SOCK } from "./config.js";
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Gera um ID único otimista (ex: "track_1678886401000_abc123") // Gera um ID único otimista (ex: "track_1678886401000_abc123")
@@ -49,7 +50,7 @@ function generateUniqueId(prefix = "item") {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// CONFIGURAÇÃO DO SOCKET.IO // CONFIGURAÇÃO DO SOCKET.IO
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
const socket = io("http://localhost:33007", { const socket = io(`https://alice.ufsj.edu.br:${PORT_SOCK}`, {
transports: ["websocket", "polling"], transports: ["websocket", "polling"],
withCredentials: true, withCredentials: true,
}); });