Next.js и TCP-сервер: при вызове функции отправки данных создается новый экземпляр сервера вместо использования существующего соединения
У меня есть Next.js проект и отдельный TCP-сервер, которые запускаются в разных терминалах (сервер запускается через node.js). При возникновении события на фронтенде мне нужно отправить данные клиенту через TCP-соединение. Я написал функцию для отправки данных, но при ее вызове (как на фронтенде, так и на бэкенде) в терминале Next.js запускается новый экземпляр TCP-сервера, из-за чего возникает ошибка занятого порта.
Проблема: вместо использования уже установленного TCP-соединения, каждый раз создается новый сервер. Как правильно организовать отправку данных через существующее соединение?
//front-end
const handleSendLink = async () => {
try {
const response = await axios.post("/api/bot/sendLink", {
id: 9,
link: "http://192.168.29.17:3000",
});
console.log(response);
} catch (error) {
console.log(error);
}
};
//back-end
import { NextApiRequest, NextApiResponse } from "next";
const { SendLink } = require("../../../servers/tcp");
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
try {
if (req.method !== "POST")
return res.status(405).json({ msg: "method not allowed" });
const body = req.body as { id: number; link: string };
if (!body.id || !body.link)
return res.status(400).json({ msg: "bad request" });
console.log("send");
SendLink(body.id, body.link);
return res.status(200).json({ msg: "link was sent" });
} catch (error) {
console.error(error);
return res.status(500).json({ msg: `Server Error: ${error}` });
}
}
//tcp server
const net = require("net");
const axios = require("axios");
const host = "http://localhost:3000";
if (!global.tcpClients) {
global.tcpClients = new Map();
}
const clients = global.tcpClients;
function SendLink(id, link) {
const socket = clients.get(id);
if (!socket) {
console.log(`Client with id ${id} is not connected`);
return;
}
socket.write(link + "\n");
console.log(`Sent link to id ${id}: ${link}`);
}
function startTcpServer() {
console.log("Initializing TCP module");
if (startTcpServer.started) return;
startTcpServer.started = true;
const server = net.createServer((socket) => {
let id = 0;
socket.on("data", async (data) => {
const message = data.toString().trim();
if (message.startsWith("id:")) {
const parts = message.split(" ");
id = parseInt(parts[1], 10);
try {
const response = await axios.post(
`${host}/api/bot/editOnlineStatus`,
{
id: id,
isOnline: true,
}
);
if (response.status === 200) {
clients.set(id, socket);
console.log("online:", id);
} else {
console.log(response.data);
}
} catch (error) {
console.error("axios error:", error.message);
}
}
});
socket.on("close", async () => {
try {
const response = await axios.post(
`${host}/api/bot/editOnlineStatus`,
{
id: id,
isOnline: false,
}
);
if (response.status === 200) {
clients.delete(id);
console.log("offline:", id);
} else {
console.log(response.data);
}
} catch (error) {
console.error("axios error:", error.message);
}
});
socket.on("error", (err) => {
console.error("socket error:", err);
});
});
server.on("error", (err) => {
if (err.code === "EADDRINUSE") {
console.error(`Port 8080 already in use`);
} else {
console.error("server error:", err);
}
});
server.listen(8080, () => {
console.log("TCP server listening on port 8080");
});
}
startTcpServer();
module.exports = {
SendLink,
};