Node JS net модуль убит / остановлен без каких-либо исключений - PullRequest
0 голосов
/ 09 февраля 2020

Я сделал простой сокет комм. клиента с помощью модуля NodeJS V10.x net и редко замечаемых проводных симптомов, которые клиент NodeJS убил без каких-либо исключений. Клиент запускается на AWS Lambda, и не было журнала исключений или сообщений об ошибках. Просто он ушел ....

Последовательность такова:

  1. Мой клиент подключается к моему серверу ECS и успешно отправляет данные команды.
  2. Сервер, если он получил любую команду, он отправил бы ACK клиенту. Конечно, он успешно отправил ACK.
  3. Иногда клиент пропускал / убивал / останавливал без каких-либо сообщений об исключениях или не смог войти в систему AWS наблюдение за облаком.

У меня нет Идея, как отследить / исправить это, пожалуйста, помогите.

Вот мой код функции, который подключает / отправляет / записывает данные на сервер, а также он пытается ... поймать.

sendDirectCmd(directCmd){
    return new Promise((resolve, reject)=>{
        let socket = net.connect(port, hostname);
        socket.setTimeout(10000); // 10 sec
        socket.on('connect', async ()=>{
            try{
                log.info('[sendCmd] connected to ECS');
                await socket.write(directCmd);
                log.info('[sendCmd] Sent Cmd');
            }catch(e){
                e.message += `\n : (requester.sendCmd.socket.on) Failed to send Cmd \n`;
                log.error('Error on connect\n', e);
                reject(e);
                socket.end();
            }
        });

        socket.on('data', (data)=>{
            resolve(data);
            socket.end();
        });

        socket.on('timeout', ()=>{
            reject(new Error(`socket Timeout `));
            socket.end();               
        });

        socket.on('error', (err)=>{
            e.message += `\n : (requester.sendCmd.socket.error)socket Error `;
            reject(err);
            socket.end();                
        });
    });
}

1 Ответ

1 голос
/ 09 февраля 2020

Я не знаю, является ли это главной или единственной проблемой, но этот фрагмент кода имеет потенциальные проблемы:

    socket.on('data', (data)=>{
        resolve(data);
        socket.end();
    });

Сокет TCP - это поток. Данные, которые вы отправляете на одном конце сокета, могут поступать на другом конце в чанке любого размера и не обязательно поступать в чанке того же размера, который отправил отправитель. Этот фрагмент кода, по-видимому, предполагает, что как только поступают какие-либо данные, все данные находятся здесь, и сокет может быть закрыт (потенциально пропуская другие данные, которые все еще поступают). Если вы не отправляете только один байт через сокет, это просто неправильно.

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

Есть много разных способов сделать это. Если ваши данные являются текстовыми, вы можете пометить конец фрагмента текста символом новой строки, нулевым символом или любым другим символом, который не встречается в ваших данных, и вы читаете данные, пока не увидите маркер, указывающий на наличие полного сообщения. , Если ваши данные не являются текстовыми, вы можете сначала отправить длину в четыре байта, которая сообщит вам, сколько байтов данных поступает. Существует множество других способов форматирования данных, чтобы вы могли знать, когда у вас есть полное сообщение / пакет.

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

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

Также см. Следующее:

Правильный способ установить sh границы для TCP-соединение

Имеет ли node js «response.on (« data », fun c (chunk))» гарантию границы чанка

NodeJs - TCP / IP Socket отправлять / получать серийно?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...