Twisted IRC Bot 与本地主机的连接反复丢失
Posted
技术标签:
【中文标题】Twisted IRC Bot 与本地主机的连接反复丢失【英文标题】:Twisted IRC Bot connection lost repeatedly to localhost 【发布时间】:2012-12-01 00:32:31 【问题描述】:我正在尝试在本地服务器上实现 IRC Bot。我使用的机器人与Eric Florenzano's Blog 中的机器人相同。这是简化的代码(应该可以运行)
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 客户端连接,它就可以工作。
我无法找到关于为什么它不断断开连接的解决方案。任何有关为什么的帮助将不胜感激。谢谢!
【问题讨论】:
你在运行哪个 IRC 服务器?是开源的吗? 有是它断开连接的某种原因,否则它不会断开连接。但是,这里没有足够的信息让任何人猜测可能是什么原因。见sscce.org和catb.org/esr/faqs/smart-questions.html @Jean-PaulCalderone - 感谢您提供这些网站。我添加了更多信息。它不属于“短”要求,但我不知道该怎么做。希望这是一个措辞更好的问题。 @fmoo 我更新了问题以包含服务器信息。它是 NGIRC,可以在 this link 找到。让我知道您是否需要更多信息。谢谢! 我在整个机器人中都没有看到 PING 或 PONG 一词。您必须向服务器发送 PING PONG 响应,否则会认为连接已断开! 【参考方案1】:您可能想做的一件事是确保在您的机器人连接到服务器时看到服务器产生的任何错误输出。我的预感是这个问题与身份验证有关,或者可能是 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
我认为这意味着...您需要进行身份验证?即使您看到其他内容,也希望这能帮助您更准确地了解关闭连接的确切原因。
另外,您可以使用tcpdump
或wireshark
来捕获ngirc 和其中一个正在工作的IRC 客户端(例如mIRC)之间的流量日志,然后比较这两个日志。无论 mIRC 发送什么不同的命令,都应该清楚地说明您需要对您的机器人进行哪些更改。
【讨论】:
谢谢!现在可以了。问题出在配置中,或者更确切地说是我对其设置缺乏了解。它返回的错误是“aerreneousnickname”。 conf 文件的昵称最大长度为 9 个字符,而我的昵称长度约为 13。以上是关于Twisted IRC Bot 与本地主机的连接反复丢失的主要内容,如果未能解决你的问题,请参考以下文章
Twisted Python IRC Bot - 如何在 bot 运行命令时监听命令?
Twisted Python IRC bot - 如何异步执行函数以便它不会阻塞机器人?
Python IRC bot 在 3 次 ping 后断开连接