Подтвердить что ты не робот

Ошибка записи после завершения в node.js веб-сервере

Я борюсь с моим хобби-проектом node.js из-за ошибки "write after end". У меня есть созданный веб-сервер node.js, который, среди прочего, отправляет команды, полученные с HTML-страницы, на другой процесс, используя следующий код:

var netSocket = require('net').Socket();
netSocket.connect(9090);
netSocket.write(messages);
netSocket.end();

Это работает до тех пор, пока трафик не начнет увеличиваться (т.е. количество отправляемых сообщений и размер сообщений). В этот момент я получаю следующую ошибку:

Error: write after end
    at writeAfterEnd (_stream_writable.js:132:12)
    at Socket.Writable.write (_stream_writable.js:180:5)
    at Socket.write (net.js:615:40)
    at Socket.<anonymous> (/Users/mark/Documents/GitHub Repos/voice_controlled_zumo/speech_module/web_server_HTTPS.js:66:15)
    at Socket.emit (events.js:95:17)
    at Socket.onevent (/Users/mark/Documents/GitHub Repos/voice_controlled_zumo/node_modules/socket.io/lib/socket.js:327:8)
    at Socket.onpacket (/Users/mark/Documents/GitHub Repos/voice_controlled_zumo/node_modules/socket.io/lib/socket.js:287:12)
    at Client.ondecoded (/Users/mark/Documents/GitHub Repos/voice_controlled_zumo/node_modules/socket.io/lib/client.js:193:14)
    at Decoder.Emitter.emit (/Users/mark/Documents/GitHub Repos/voice_controlled_zumo/node_modules/socket.io/node_modules/socket.io-parser/node_modules/component-emitter/index.js:134:20)

Я предполагаю, что сервер на 9090 перегружен количеством трафика, что приводит к ошибке. Будучи полноправным новичком в мире node.js, я бы очень признателен за любые подсказки о том, как я могу решить эту проблему.

Обратите внимание, что веб-сервер обслуживает страницы через SSL (в случае, если это имеет значение).

Спасибо, что нашли время, чтобы прочитать это!

Марк

4b9b3361

Ответ 1

node.js - неблокирующая асинхронная платформа.

В вашем случае

netSocket.write(messages);

- это метод Async, поэтому netSocket.end() вызывается до завершения записи.

правильное использование:

netSocket.write(messages, function(err) { netSocket.end(); });

Второй аргумент здесь - функция обратного вызова, которая будет вызываться после того, как метод write напишет свое задание.

Я бы порекомендовал вам читать/смотреть больше о node.js, стилях асинхронизации и обратных вызовах.

вот отличное место для начала: https://www.youtube.com/watch?v=GJmFG4ffJZU

И, конечно, node.js API docs относительно сетевых сокетов.

Надеюсь, что это помогло:)

Ответ 2

Во-первых, я думаю, что в другом ответе есть сообщения об ошибках socket.write() и socket.end(). Совершенно нормально и нормально делать их обратно к спине в одном тике:

socket.write(everythingIPlanToSend);
socket.end();

Вам не нужно предоставлять обратный вызов write. Обратный вызов скажет вам, когда данные были полностью выведены из соединения, но это необязательное уведомление, которое типичным программам не нужно беспокоиться.

Однако, глядя на вашу трассировку стека, я думаю, что ваш поток управления обработкой событий нарушен таким образом. У вас подключен клиент socket.io, который выдает события, которые вы слушаете. Когда эти события срабатывают, вы отправляете их на ваш восходящий сервер. Затем вы завершаете восходящее соединение сокета. В этот момент вы должны развязать (removeListener) ваш прослушиватель сокета socket.io, чтобы при поступлении большего количества событий вы не пытались отправить им соединение, которое вы уже закрыли.

Другой способ сказать, что всякий раз, когда вы вызываете .end() в своем восходящем сокете, вы должны убедиться, что будущие входящие события из браузера не используют тот же сокет. ИЛИ вам нужно изменить свой код, чтобы использовать один и тот же восходящий сокет для всех событий из соответствующего сокета браузера (что, вероятно, более эффективно/правильно), НО в этом случае не называть .end() на нем, пока разводка браузера фактически не отключается.

Ответ 3

У меня была аналогичная проблема с сжатием модуля node, после того как я обновил его до последней версии 1.6, проблема была решена.

npm install [email protected]