Почему происходит сбой сервера при втором запросе? - PullRequest
4 голосов
/ 02 августа 2011

У меня есть сервер nodejs, как показано ниже. Сервер может устанавливать заголовки, когда оператор res.header () не находится внутри события. Сбой, когда он выполняется в resposne к событию, например, так:

app.get('/m/ad', function (req, res) {
  adManager.on('ad_unit_exists', function (ad_unit) {                 
    res.header('Ad-Type',"html");
    res.end();
    return;
  });
  adManager.emit('ad_unit_exists',{});
});

Редактировать: Ошибка означает, что сервер падает со следующей ошибкой:

Error: Can't set headers after they are sent.
    at ServerResponse.<anonymous> (http.js:526:11)
    at ServerResponse.setHeader (/home/raj/node_modules/express/node_modules/connect/lib/patch.js:44:20)
    at ServerResponse.header (/home/raj/node_modules/express/lib/response.js:242:10)
    at EventEmitter.<anonymous> (/home/raj/Projects/adreactor-node/server.js:227:28)
    at EventEmitter.emit (events.js:81:20)
    at Object.<anonymous> (/home/raj/Projects/adreactor-node/server.js:232:16)
    at nextMiddleware (/home/raj/node_modules/express/lib/router/index.js:139:34)
    at param (/home/raj/node_modules/express/lib/router/index.js:147:16)
    at pass (/home/raj/node_modules/express/lib/router/index.js:155:10)
    at Object.router [as handle] (/home/raj/node_modules/express/lib/router/index.js:161:6)

Почему вы думаете, что это?

РЕДАКТИРОВАТЬ: Запросы отлично работает для первого запроса. Сбой сервера при втором запросе.

Ответы [ 2 ]

3 голосов
/ 02 августа 2011

Переменная adManager является глобальной переменной.По какой-то причине он сохраняет аргументы для обработчиков событий.

Я использовал adManager как своего рода глобальный объект EventEmitter для отправки событий и управления потоком кода.

У меня был дополнительный оператор снаружи, например, который инициализировал adManager при запуске сервера:

 app.get('/m/ad', function (req, res) {

        adManager.on('ad_unit_exists', function (ad_unit, req, res) {               
                   res.header('Ad-Type',"html");

           res.end();
           return;
        });

    adManager.emit('ad_unit_exists',{}, req, res);    
});

AdManager.prootype = new process.EventEmitter();
var adManager = new AdManager();

res в обратном вызове для события ad_unit_exists анализировал res из предыдущего событияэмиссия - предыдущий запрос, который уже завершился () 'ed - когда событие было отправлено для второго запроса.Странный.

Решил это, добавив:

adManager = new AdManager() 

в функцию обратного вызова app.get ().

2 голосов
/ 02 августа 2011

Я не думаю, что этот код может дать нам полную картину (функция не завершена?). Ошибка говорит нам, что вы пишете в сокет два раза. Возможно, res.end() вызывается два раза, а не один раз. Вы должны поместить несколько операторов отладки (console.log) между ними, чтобы получить лучшую картину.

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