使用chat irc bot发送快递后无法设置标题

时间:2015-08-17 17:44:34

标签: javascript json node.js http

我正在构建一个聊天机器人,可以缓和聊天并响应用户在聊天中发送的命令。

我也试图在快速服务器中设置它,这样我就可以启动和停止机器人以及在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...

1 个答案:

答案 0 :(得分: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'});
});