POP3-диалог с gmail и node.js

Я пытаюсь написать простой клиент POP3 для Gmail в node.js. Сначала я написал один, в котором я ввожу команды POP3, и они отправляются на сервер, и сервер отвечает. Это нормально работает, потому что я могу дождаться ответа сервера, прежде чем вводить следующую команду.

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

stream.write('USER ***&@gmail.com');
stream.write('PASS *****');
stream.write('LIST');

не работает из-за асинхронного характера потоков в node. Мне нужно дождаться события потока данных перед отправкой следующего сообщения, иначе ничего не произойдет. Итак, попробовал вот так:

var tls =require ('tls');

var stream = tls.connect(995,'pop.gmail.com', function() {
    console.log ('Conexion establecida');
});

stream.on('data', function(data)
{
    var str = data.toString();
    console.log(str.substr(0,14));
    if(str.substr(0,14)=="+OK Gpop ready")
    {
        console.log('Sending username...');
        process.nextTick(function() {
            stream.write ('USER ***********@gmail.com');
        });
    }

    if(str.substr(0,14)=="+OK send PASS")
    {
        console.log('Recieving list of email...');
        process.nextTick(function(){
            stream.write('PASS *********');
        });
    }
});

Идея состоит в том, что прослушиватель событий data обрабатывает отправку следующей команды в зависимости от последнего полученного ответа. Опять же, выполнение только stream.write не помогло, поэтому я заключил вызовы write () в вызовы process.nextTick (). Кажется, что команда USER отправлена, а команда PASS - никогда. Может кто-нибудь сказать мне, почему? Или есть более эффективный способ сделать это? Спасибо за любую информацию.


person tutiplain    schedule 20.10.2013    source источник
comment
fyi: substr второй параметр - длина. У вас всего 13 символов, но вы сравниваете 14.   -  person WiredPrairie    schedule 20.10.2013
comment
Спасибо, но даже после исправления ничего не отправляется.   -  person tutiplain    schedule 20.10.2013
comment
Я попробовал и вернулся -ERR bad command после отправки USER   -  person WiredPrairie    schedule 20.10.2013
comment
В моем случае единственным ответом, который я получил от сервера, было исходное сообщение + OK Gpop is ready for requests. После отправки USER больше ничего не происходит, даже сообщения об ошибке. Обратите внимание: я пробовал этот код на двух разных машинах в разных местах с одинаковым результатом. Это определенно не проблема брандмауэра. Кроме того, я сделал клиента, в котором вы вводите команды в консоли, а он их отправляет. Это отлично работает в обоих местах.   -  person tutiplain    schedule 20.10.2013


Ответы (2)


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

Кроме того, вы можете упростить свои команды, реализовав такую ​​очередь:

var tls = require('tls');
var commands = [];

commands.push('USER ***********@gmail.com\n');
commands.push('PASS *********\n');

var stream = tls.connect(995, 'pop.gmail.com', function () {
    console.log('Conexion establecida');
});

stream.on('data', function (data) {
    if (data.toString().indexOf('OK') > -1 && commands.length) {
        stream.write(commands.shift());
    }
});
person levi    schedule 20.10.2013
comment
Похоже, это не работает. Я добавил console.log(data.toString()) в начале события данных, чтобы увидеть, что происходит. Принято только первое сообщение (+ OK Gpop ready ...). - person tutiplain; 20.10.2013
comment
Спасибо! Как вы и сказали, мне не хватало символа новой строки. Теперь работает. - person tutiplain; 21.10.2013

Не видя всего кода, ответить немного сложно.

Однако я заметил, что в вашем первом примере вы пишете

stream.write ('ПОЛЬЗОВАТЕЛЬ * [email protected]');

с амперсандом "&"

Однако во втором примере амперсанда нет - может ли это быть источником проблемы?

person GMauro    schedule 20.10.2013
comment
Амперсанд был опечаткой. Я не использую это в своем реальном примере. - person tutiplain; 20.10.2013