1

我正在尝试在本地服务器上实现 IRC Bot。我使用的机器人与Eric Florenzano 的博客中的机器人相同。这是简化的代码(应该运行)

import sys
import re
from twisted.internet import reactor
from twisted.words.protocols import irc
from twisted.internet import protocol

class MomBot(irc.IRCClient):
    def _get_nickname(self):
        return self.factory.nickname
    nickname = property(_get_nickname)

    def signedOn(self):
        print "attempting to sign on"
        self.join(self.factory.channel)
        print "Signed on as %s." % (self.nickname,)

    def joined(self, channel):
        print "attempting to join"
        print "Joined %s." % (channel,)

    def privmsg(self, user, channel, msg):
        if not user:
            return
        if self.nickname in msg:
            msg = re.compile(self.nickname + "[:,]* ?", re.I).sub('', msg)
            prefix = "%s: " % (user.split('!', 1)[0], )
        else:
            prefix = ''
        self.msg(self.factory.channel, prefix + "hello there")


class MomBotFactory(protocol.ClientFactory):
    protocol = MomBot

    def __init__(self, channel, nickname='YourMomDotCom', chain_length=3,
        chattiness=1.0, max_words=10000):
        self.channel = channel
        self.nickname = nickname
        self.chain_length = chain_length
        self.chattiness = chattiness
        self.max_words = max_words

    def startedConnecting(self, connector):
        print "started connecting on {0}:{1}" 
            .format(str(connector.host),str(connector.port))

    def clientConnectionLost(self, connector, reason):
        print "Lost connection (%s), reconnecting." % (reason,)
        connector.connect()

    def clientConnectionFailed(self, connector, reason):
        print "Could not connect: %s" % (reason,)

if __name__ == "__main__":
    chan = sys.argv[1]
    reactor.connectTCP("localhost", 6667, MomBotFactory('#' + chan,
        'YourMomDotCom', 2, chattiness=0.05))
    reactor.run()

我在客户端工厂中添加了 startedConnection 方法,它正在到达并打印出正确的地址:主机。然后它断开连接并进入 clientConnectionLost 并打印错误:

Lost connection ([Failure instance: Traceback (failure with no frames):
    <class 'twisted.internet.error.ConnectionDone'>: Connection was closed cleanly.
    ]), reconnecting.

如果工作正常,它应该登录到适当的频道,指定为命令中的第一个参数(例如,python module2.py botwar。将是频道#botwar。)。如果频道中的任何人发送任何内容,它应该以“hello there”响应。

我在服务器上运行NGIRC ,如果我从 mIRC 或任何其他 IRC 客户端连接,它就可以工作。

我无法找到解决它为什么会不断断开连接的解决方案。任何有关为什么的帮助将不胜感激。谢谢!

4

1 回答 1

2

您可能想要做的一件事是确保当您的机器人连接到服务器时您会看到服务器产生的任何错误输出。我的预感是问题与身份验证有关,或者可能是 ngirc 处理IRCClient.

几乎总是适用的一种方法是捕获流量日志。使用 tcpdump 或 wireshark 之类的工具。

您可以尝试的另一种方法是在 Twisted 应用程序本身内启用日志记录。用于twisted.protocols.policies.TrafficLoggingFactory此:

from twisted.protocols.policies import TrafficLoggingFactory
appFactory = MomBotFactory(...)
logFactory = TrafficLoggingFactory(appFactory, "irc-")
reactor.connectTCP(..., logFactory)

这会将输出记录到以“irc-”开头的文件(每个连接的不同文件)。

您还可以在多个级别中的任何一个级别直接挂钩到您的协议实现。例如,要显示接收到的任何字节:

class MomBot(irc.IRCClient):
    def dataReceived(self, bytes):
        print "Got", repr(bytes)
        # Make sure to up-call - otherwise all of the IRC logic is disabled!
        return irc.IRCClient.dataReceived(self, bytes)

使用其中一种方法,希望您会看到如下内容:

:irc.example.net 451 * :Connection not registered

我认为这意味着...您需要进行身份验证?即使您看到其他内容,也希望这能帮助您更深入地了解关闭连接的确切原因。

此外,您可以使用tcpdumpwireshark捕获 ngirc 和其中一个正在工作的 IRC 客户端(例如 mIRC)之间的流量日志,然后比较这两个日志。无论 mIRC 发送什么不同的命令,都应该清楚地说明您需要对您的机器人进行哪些更改。

于 2012-12-04T16:31:53.020 回答