didvan-app/server.js

167 lines
6.0 KiB
JavaScript

// import express from "express";
// import http from "http";
// import { Server } from "socket.io";
// import { GoogleGenAI, Modality } from "@google/genai";
// import path from "path";
// import { fileURLToPath } from "url";
// const __filename = fileURLToPath(import.meta.url);
// const __dirname = path.dirname(__filename);
// const app = express();
// const server = http.createServer(app);
// const io = new Server(server, {
// cors: {
// origin: "*",
// methods: ["GET", "POST"]
// }
// });
// app.use(express.static(path.join(__dirname, "public")));
// // ⚠️ کلید API خود را اینجا قرار دهید
// const ai = new GoogleGenAI({
// apiKey: "AIzaSyC9kWntTutd2jnUvY7IqMAozZAOeZ47QUE"
// });
// // مدل مناسب برای Gemini Live
// const model = "gemini-2.5-flash-native-audio-preview-09-2025";
// const config = {
// responseModalities: [Modality.AUDIO],
// systemInstruction: "You are a helpful voice assistant. Always respond with audio. You are called 'دستیار صوتی هوشمند دیدوان'. Respond concisely in the same language as the user."
// };
// io.on("connection", async (socket) => {
// console.log("✅ Client connected:", socket.id);
// let session;
// let audioChunkCount = 0;
// let receivedChunkCount = 0;
// try {
// // اتصال به Gemini Live API
// session = await ai.live.connect({
// model,
// config,
// callbacks: {
// onmessage: (msg) => {
// // Log complete message structure for debugging
// if (msg?.setupComplete) {
// console.log("📩 Gemini: Setup Complete");
// return;
// }
// if (msg?.toolCall || msg?.toolCallCancellation) {
// console.log("📩 Gemini: Tool call (ignoring)");
// return;
// }
// console.log("📩 Raw Gemini Message:", JSON.stringify(msg).substring(0, 500));
// // ✅ بررسی مسیر اول: msg.data (برای استریم‌های مستقیم صوتی)
// if (msg?.data) {
// const base64Audio = msg.data;
// audioChunkCount++;
// console.log("🔊 [Route 1] Sending audio chunk #" + audioChunkCount + ": " + base64Audio.length + " chars");
// socket.emit("gemini_audio_chunk", base64Audio);
// return;
// }
// // ✅ بررسی مسیر دوم: msg.serverContent.modelTurn.parts
// if (msg?.serverContent?.modelTurn?.parts) {
// console.log("📦 Found serverContent.modelTurn.parts, checking for audio...");
// const parts = msg.serverContent.modelTurn.parts;
// for (const part of parts) {
// // Log part structure
// console.log(" Part keys:", Object.keys(part));
// if (part.text) {
// console.log(" 📝 Text part:", part.text);
// }
// if (part.inlineData) {
// console.log(" 💾 InlineData mimeType:", part.inlineData.mimeType);
// console.log(" 💾 InlineData size:", part.inlineData.data?.length || 0, "chars");
// if (part.inlineData.mimeType?.startsWith("audio/")) {
// const base64Audio = part.inlineData.data;
// const mimeType = part.inlineData.mimeType;
// audioChunkCount++;
// console.log("🔊 [Route 2] Sending audio chunk #" + audioChunkCount + ": " + base64Audio.length + " chars, mime: " + mimeType);
// // ارسال به کلاینت با اطلاعات mime
// socket.emit("gemini_audio_chunk", {
// data: base64Audio,
// mimeType: mimeType
// });
// }
// }
// }
// }
// // ✅ بررسی پایان نوبت
// if (msg?.serverContent?.turnComplete) {
// console.log("✅ Gemini turn complete");
// }
// },
// onerror: (e) => {
// console.error("❌ Gemini Session Error:", e);
// socket.emit("error", "Gemini connection error");
// },
// onclose: (event) => {
// console.log("🔒 Gemini session closed:", event?.code, event?.reason);
// }
// }
// });
// console.log("✨ Gemini Session Connected for client:", socket.id);
// } catch (e) {
// console.error("🔥 Failed to connect to Gemini:", e);
// socket.emit("error", "Failed to connect to AI service");
// return;
// }
// // ✅ دریافت صدا از کلاینت فلاتر
// socket.on("audio_chunk", async (base64Chunk) => {
// if (!session) {
// console.error("⚠️ No active Gemini session");
// return;
// }
// receivedChunkCount++;
// console.log("📥 Received chunk #" + receivedChunkCount + " from client: " + base64Chunk.length + " chars");
// try {
// // ✅ فرمت صحیح برای ارسال به Gemini Live API
// await session.sendRealtimeInput([{
// mimeType: "audio/pcm;rate=16000",
// data: base64Chunk
// }]);
// console.log("✅ Sent chunk #" + receivedChunkCount + " to Gemini");
// // Gemini should auto-detect turn completion based on audio silence
// } catch (e) {
// console.error("❌ Error sending chunk to Gemini:", e.message, e.stack);
// }
// });
// socket.on("disconnect", () => {
// console.log("❌ Client disconnected: " + socket.id);
// console.log("📊 Stats - Received: " + receivedChunkCount + " chunks, Sent: " + audioChunkCount + " chunks");
// if (session) {
// session.close();
// session = null;
// }
// });
// });
// const PORT = 3001;
// server.listen(PORT, "0.0.0.0", () => {
// console.log(`🚀 Server running on port ${PORT}`);
// console.log(`🌐 Access from network: http://<YOUR_IP>:${PORT}`);
// });