Отправка данных с помощью node-fetch в node.js в Pure Data (Pd) приводит к ETIMEDOUT

Я создаю звуковую установку, которая загружает информацию о погоде и переводит ее в звук. Кроме того, я сделал простой html-сайт на p5.js, который позволяет пользователю отключать громкость и использовать ползунок для воспроизведения музыки. Все аккуратно интегрировано в сервер node.js.

Данные отправляются из файла sketch.js в файл server.js с помощью socket.io. Данные с сервера отправляются в Pure data с помощью пакета узла, называемого node-fetch, где они принимаются с помощью объекта [netreceive]. Все это делается через локальный хост (http://ip-адрес:порт).

К проблеме: все работает отлично, но примерно через три-шесть часов сервер узла, похоже, теряет соединение с Pd (чистые данные) и завершает работу. Я перезагружаю, и происходит то же самое. Сообщение об ошибке гласит:

Sep 24 14:55:52 raspberrypi bash[7530]: (node:7561) UnhandledPromiseRejectionWarning: FetchError: request to http://192.168.1.219:3558/ failed, reason: connect ETIMEDOUT 192.168.1.219:3558
Sep 24 14:55:52 raspberrypi bash[7530]:     at ClientRequest.<anonymous> (/home/pi/Documents/pd2_repository/node_modules/node-fetch/lib/index.js:1455:11)
Sep 24 14:55:52 raspberrypi bash[7530]:     at ClientRequest.emit (events.js:198:13)
Sep 24 14:55:52 raspberrypi bash[7530]:     at Socket.socketErrorListener (_http_client.js:401:9)
Sep 24 14:55:52 raspberrypi bash[7530]:     at Socket.emit (events.js:198:13)
Sep 24 14:55:52 raspberrypi bash[7530]:     at emitErrorNT (internal/streams/destroy.js:91:8)
Sep 24 14:55:52 raspberrypi bash[7530]:     at emitErrorAndCloseNT (internal/streams/destroy.js:59:3)
Sep 24 14:55:52 raspberrypi bash[7530]:     at process._tickCallback (internal/process/next_tick.js:63:19)
Sep 24 14:55:52 raspberrypi bash[7530]: (node:7561) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 735)

Я понятия не имею, с чего начать искать ответы: ошибка в моем sketch.js, в server.js, в Pd или это как-то связано с интернетом? Это не должно быть проблемой прокси, так как я запускаю его на локальном хосте, верно?

Вот пример из моего sketch.js:

function setup() {
  noCanvas();

  // Start a socket connection to the server
  socket = io.connect(url + ':3000');

async function getISS() {
    const response = await fetch(api_url);
    const data = await response.json();
    console.log(data.timeSeries[2].validTime);

    var smhiData = {
      pcat: data.timeSeries[2].parameters[2].level,
      sunUp: 6,
      sunDown: 20
    };
    socket.emit('smhiToPd', smhiData); 
}

А вот пример сервера:

io.sockets.on('connection', newConnection);

// We are given a websocket object in our function
function newConnection(socket) {
    console.log('We have a new client: ' + socket.id);
socket.on('smhiToPd', smhi);

    async function smhi(data){
        pcat = data.pcat;

        fetch("http://" + ip + ":" + 3558, {
            method: "PUT", 
            body: ";pcat " + pcat + ";"
        });
    }
}

А вот как это выглядит в Pd: Netreceive-object прослушивает порт 3558

Pd и Node запускаются с помощью скрипта запуска systemd.

Немного информации о Pd: Версия: 0.51-2. Флаги: -rt и -nogui. Скорость звука: 48 кГц. Размер блока: 64. Задержка: 512.

Компьютер представляет собой Raspberry Pi 4 под управлением Raspbian. Процесс Pd работает примерно на 15-35% ЦП.

PS Очень благодарен за любую помощь. Обратите внимание, я новичок, и мои навыки и знания в области программирования очень ограничены. Я сделаю все возможное, чтобы понять любые ваши ответы или идеи!

PPS Я знаю, что мне еще предстоит реализовать .catch на сервере. Я только что реализовал это в своем коде и жду очередного сбоя.

РЕДАКТИРОВАТЬ: В настоящее время bash выдает это сообщение об ошибке, по крайней мере, 50 сообщений в секунду, а pd работает почти на 100% ЦП.

Sep 25 07:46:52 raspberrypi bash[10566]: netreceive: accept failed
Sep 25 07:46:52 raspberrypi bash[10566]: netreceive: accept failed
Sep 25 07:46:52 raspberrypi bash[10566]: netreceive: accept failed
Sep 25 07:46:52 raspberrypi bash[10566]: netreceive: accept failed
Sep 25 07:46:52 raspberrypi bash[10566]: netreceive: accept failed
Sep 25 07:46:52 raspberrypi bash[10566]: netreceive: accept failed
Sep 25 07:46:52 raspberrypi bash[10566]: netreceive: accept failed
Sep 25 07:46:52 raspberrypi bash[10566]: netreceive: accept failed
Sep 25 07:46:52 raspberrypi bash[10566]: netreceive: accept failed

Кажется, я нашел исходный код [netreceive]. Вот часть о том, что принять не удалось. Кто-нибудь может понять это?

static void netreceive_connectpoll(t_netreceive *x)
{
    int fd = accept(x->x_connectsocket, 0, 0);
    if (fd < 0) post("netreceive: accept failed");
    else
    {
        t_socketreceiver *y = socketreceiver_new((void *)x, 
            (t_socketnotifier)netreceive_notify,
                (x->x_msgout ? netreceive_doit : 0), 0);
        sys_addpollfn(fd, (t_fdpollfn)socketreceiver_read, y);
        outlet_float(x->x_connectout, ++x->x_nconnections);
    }
}

person notna242    schedule 24.09.2020    source источник


Ответы (1)


Я нашел ответ на то, что вызывает закрытие соединения и зависание компьютера. Дело в том, что [netreceive] Pd открывает новое соединение каждый раз, когда получает новое сообщение. Это отлично работает для пары подключений, но по мере увеличения количества подключений нагрузка становится все больше и больше, что в конечном итоге приводит к зависанию компьютера.

Почему Pd открывает новое соединение каждый раз, когда получает данные? Не уверена. Это как-то связано с протоколом TCP?

person notna242    schedule 29.09.2020