不能设置标题后,他们发送聊天irc机器人在express

Can't set headers after they are sent with chat irc bot in express

本文关键字:irc 聊天 机器人 express 标题 设置 他们 不能      更新时间:2023-09-26

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

我也试图在一个快速服务器设置这个,所以我可以启动和停止机器人以及管理命令等在一个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);
...

In 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;

In 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调用来启动和停止bot。当startBot端点被击中时,问题发生,然后stopBot,然后startBot再次被调用,bot连接到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...

这个问题与你添加的事件处理程序在同一个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'});
});