Как передать функцию с сервера на клиент socket.io

Есть Сервер:

const express = require("express");
const { createServer } = require("http");
const { Server } = require("socket.io");

// Client Payload

function calculateSquare(number) {
  return number * number;
}
// Client Payload

const app = express();
const server = createServer(app);
const io = new Server(server, {
  cors: {
    origin: "*",
    methods: ["GET", "POST", "PUT", "DELETE"],
  },
});

app.get("/", (req, res) => {
  res.send("<h1>Hello server</h1>");
});

io.on("connection", (socket) => {
  console.log("a user connected");

  socket.emit("function", {
    // Тут нужно отправить функцию клиенту
  });
});

server.listen(3000, () => {
  console.log("server running at http://localhost:3000");
});

Тут нужно просто отправить функцию calculateSquare клиенту через emit, как это сделать? пробовал делать через передачи функции в виде строки и потом через eval() выполнять этот код в клиенте, но оно не работало.

Вот пример клиента:

import { useState, useEffect } from "react";
import "./App.css";
import io from "socket.io-client";

function App() {
  const [message, setMessage] = useState("");

  useEffect(() => {
    const socket = io("http://localhost:3000", {});

    socket.on("function", (data) => {
      // Тут мы получаем функцию. Результат можно просто в console.log()
    });
    return () => {
      socket.disconnect();
    };
  }, []);

  return (
    <div className="wrapper">
      <p>Hello there</p>
      <p>Message from server: {message}</p>
    </div>
  );
}

export default App;

Ответы (1 шт):

Автор решения: SwaD

Использовать осторожно!

Вообще это крайне плохо, когда у вас есть функционал получения тела функции и ее выполнения. Однако, если вам уж очень надо, то можно сделать так:

На сервере определяем параметры функции(аргументы, которые требуются для работы) и тело самой функции.

socket.emit("function", {
  param: ['a', 'b'],
  fnBody: `const v = 5;
  return a * b + v;`
});

На клиенте создаем фукнцию при помощи new Function ну и помещаем в какую нибудь переменную для дальнейшего использования

socket.on("function", (data) => {
  const fn = new Function(...data.param, data.fnBody);
  console.log(fn(1,2));
})
→ Ссылка