【问题标题】:Can't set headers after they are sent with chat irc bot in express使用聊天 irc bot 以快递方式发送后无法设置标头
【发布时间】:2015-08-17 17:44:34
【问题描述】:

我正在构建一个聊天机器人,它将调节聊天并响应用户在聊天中发送的命令。

我还尝试在快速服务器中进行设置,这样我就可以启动和停止机器人以及在 Web 应用程序中管理命令等,这样我就不必从我的终端上运行机器人了时间。

我的文件设置类似于 express-generator 这样

node_modules
routes
  - api
    - bot.js
  api.js
server.js

在 server.js 中

...
var api = require('./routes/api');

app.use('/api/v'+apiVersion, api);
...

routes/api.js

var express = require('express');
var router = express.Router();

// API's
var bot = require('./api/bot');

// Endpoints
router.route('/bot')
    .post(function(req,res) { bot.startBot(req,res) })
    .delete(function(req,res) { bot.stopBot(req,res) });

module.exports = router;

routes/api/bot.js

var config = require('../../config');

var irc = require('tmi.js');

var chatBotOptions = {
  options: {
    debug: true,
  },
  identity: {
    username: config.username,
    password: config.password
  },
  channels: config.channels
};
var chatBot = new irc.client(chatBotOptions);

module.exports.startBot = function(req,res){
  // Connect chatBot
  chatBot.connect();
  chatBot.on('join', function(channel, username){
    chatBot.say(channel, 'Hello there!');
    res.json({action:'joined'});
  });
};
module.exports.stopBot = function(req,res){
  // Disconnect chatBot
  chatBot.say(config.channels[0],"I'm out!");
  chatBot.disconnect();
  res.json({action:'disconnecting'});
};
chatBot.on('chat', function(channel, user, message, self){
  chatBot.say(channel, "Kappa");
});

在我的前端,我使用正确的 http 动词对这些端点进行 ajax 调用来启动和停止机器人。当startBot 端点被命中,然后stopBot 然后startBot 再次被调用,机器人连接到irc 通道,但我猜当res.json 消息被发送时,我得到了这个错误。我正在阅读这与各种回调有关,但我只是不确定那会在哪里,因为 res.json 只发送到一个地方,我什至不确定这是否是问题所在。

这是错误堆栈

_http_outgoing.js:335
    throw new Error('Can\'t set headers after they are sent.');
          ^
Error: Can't set headers after they are sent.
    at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:335:11)
    at ServerResponse.header (/Users/jordanriser/workspace/twitch_bot/node_modules/express/lib/response.js:718:10)
    at ServerResponse.send (/Users/jordanriser/workspace/twitch_bot/node_modules/express/lib/response.js:163:12)
    at ServerResponse.json (/Users/jordanriser/workspace/twitch_bot/node_modules/express/lib/response.js:249:15)
    at client.<anonymous> (/Users/jordanriser/workspace/twitch_bot/routes/api/bot.js:25:9)
    at client.emit (events.js:129:20)
    at client.handleMessage (/Users/jordanriser/workspace/twitch_bot/node_modules/tmi.js/lib/client.js:362:30)
    at /Users/jordanriser/workspace/twitch_bot/node_modules/tmi.js/lib/client.js:602:18
    at Array.forEach (native)
    at client._onMessage (/Users/jordanriser/workspace/twitch_bot/node_modules/tmi.js/lib/client.js:600:11)
17 Aug 13:39:05 - [nodemon] app crashed - waiting for file changes before starting...

【问题讨论】:

    标签: javascript json node.js http


    【解决方案1】:

    问题与您添加的事件处理程序有关,该事件处理程序在同一个 EventEmitter 实例上多次执行。

    所以这个:

    chatBot.on('join', function(channel, username){
      chatBot.say(channel, 'Hello there!');
      res.json({action:'joined'});
    });
    

    应该改为:

    // .once() instead of .on()
    chatBot.once('join', function(channel, username){
      chatBot.say(channel, 'Hello there!');
      res.json({action:'joined'});
    });
    

    但是,如果发出请求的客户端在发出 join 事件之前提前关闭连接,这仍然可能导致错误。为了解决这个问题,您可以在调用 res.json() 之前检查请求的套接字是否仍可写:

    chatBot.once('join', function(channel, username){
      chatBot.say(channel, 'Hello there!');
      if (req.socket.writable)
        res.json({action:'joined'});
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-06
      相关资源
      最近更新 更多