Python twisted:函数调用不正确?
我在设置连接到“分发服务器”以发送特定数据的客户端时遇到问题。 服务器的目的是从客户端获取数据,然后将数据发送到所有连接的客户端。服务器工作时没有任何问题。 主客户端也应该作为IRC bot工作。 下面是一个文本示例,说明它的工作原理: 约翰:你好 一,。IRC客户端收到消息,我们需要立即将其发送给分发服务器 二,。分发服务器应获取此“John:您好!”字符串,并将其发送回所有已连接的客户端 三,。如果其他客户端向分发服务器发送数据,这将广播给所有客户端,IRC客户端应将接收到的数据输出到指定的通道 以下代码是IRC bot客户端(ircbot.py): 我希望客户端将所有传入的聊天数据从IRC服务器输出到“分发服务器”服务器,并从“分发服务器”输出传入的数据。 但是,我会遇到如下错误:Python twisted:函数调用不正确?,python,client,twisted,irc,Python,Client,Twisted,Irc,我在设置连接到“分发服务器”以发送特定数据的客户端时遇到问题。 服务器的目的是从客户端获取数据,然后将数据发送到所有连接的客户端。服务器工作时没有任何问题。 主客户端也应该作为IRC bot工作。 下面是一个文本示例,说明它的工作原理: 约翰:你好 一,。IRC客户端收到消息,我们需要立即将其发送给分发服务器 二,。分发服务器应获取此“John:您好!”字符串,并将其发送回所有已连接的客户端 三,。如果其他客户端向分发服务器发送数据,这将广播给所有客户端,IRC客户端应将接收到的数据输出到指定的
def signedOn(self):
self.msg("NickServ", "id <password_removed>") # Identify the bot
time.sleep(0.1) # Wait a little...
self.join(self.factory.channel) # Join channel #chantest
print "Signed on as %s." % (self.nickname,)
def buildProtocol(self, addr):
print 'Connected to the Distributor'
self.connection = EchoClient()
return self.connection
对于ircbot.py中的以下行
EchoClient().sendData('IRC'+' '.join(map(str, [name, msg])))
我得到以下错误:
Joined #chantest.
Longdouble: test
Traceback (most recent call last):
File "C:\Python\lib\site-packages\twisted\internet\tcp.py", line 460, in doRea
d
return self.protocol.dataReceived(data)
File "C:\Python\lib\site-packages\twisted\words\protocols\irc.py", line 2277,
in dataReceived
basic.LineReceiver.dataReceived(self, data.replace('\r', ''))
File "C:\Python\lib\site-packages\twisted\protocols\basic.py", line 564, in da
taReceived
why = self.lineReceived(line)
File "C:\Python\lib\site-packages\twisted\words\protocols\irc.py", line 2285,
in lineReceived
self.handleCommand(command, prefix, params)
--- <exception caught here> ---
File "C:\Python\lib\site-packages\twisted\words\protocols\irc.py", line 2329,
in handleCommand
method(prefix, params)
File "C:\Python\lib\site-packages\twisted\words\protocols\irc.py", line 1813,
in irc_PRIVMSG
self.privmsg(user, channel, message)
File "C:\Python\Traance\kwlbot\ircbot.py", line 51, in privmsg
EchoClient().sendData('IRC'+' '.join(map(str, [name, msg])))
File "C:\Python\Traance\kwlbot\ircbot.py", line 90, in sendData
self.transport.write(data)
exceptions.AttributeError: 'NoneType' object has no attribute 'write'
->
我做错了什么?如何从IRCbot类调用正确的函数,使其将数据发送到分发服务器,并将从分发服务器接收到的数据通过IRC输出到指定的通道
欢迎提出任何建议和可能的解决方案
如果我遗漏了任何其他细节,请告诉我
谢谢你抽出时间
TFM
从未在您的代码中定义,因此我不知道有什么交易
另一个错误是,您正在实例化一个客户端,但从未将其连接到任何东西,如reactor.connectTCP(…)
或endpoint.connect(…)
。transport
属性将为None
,直到它被某个设置
(这将有助于您找到一个更简单的代码版本,它是完整的,不包括所有打印的日志消息等不必要的细节。这将使您更难看到真正的问题。)您应该避免编写这样的阻塞代码:
def signedOn(self):
self.msg("NickServ", "id <password_removed>") # Identify the bot
time.sleep(0.1) # Wait a little...
self.join(self.factory.channel) # Join channel #chantest
print "Signed on as %s." % (self.nickname,)
def buildProtocol(self, addr):
print 'Connected to the Distributor'
self.connection = EchoClient()
return self.connection
您正在创建一个协议实例,该实例负责处理连接,然后尝试使用它,但您没有创建连接。发送数据的尝试失败,因为协议尚未连接到任何传输
您的代码片段已经两次演示了创建连接的正确方法:
IRC = BotFactory('#chantest')
reactor.connectTCP('irc.rizon.net', 6667, IRC) # Our IRC connection
f = EchoFactory()
reactor.connectTCP("localhost", 8000, f) # Connection to the Distributor server
错误在于创建一个新的EchoClient
实例,一个没有连接的实例。reactor.connectTCP
调用创建一个新连接和一个新的EchoClient
实例,并将它们彼此关联起来
您希望使用工厂创建的EchoClient
实例,而不是EchoClient().sendData(…)
:
def buildProtocol(self, addr):
print 'Connected to the Distributor'
return EchoClient()
您的buildProtocol
实现创建了该实例,所缺少的只是保存该实例,以便您的IRC bot可以使用它
考虑一下这样的情况:
def signedOn(self):
self.msg("NickServ", "id <password_removed>") # Identify the bot
time.sleep(0.1) # Wait a little...
self.join(self.factory.channel) # Join channel #chantest
print "Signed on as %s." % (self.nickname,)
def buildProtocol(self, addr):
print 'Connected to the Distributor'
self.connection = EchoClient()
return self.connection
然后,您的IRC客户端可以使用保存的EchoClient
实例:
if channel == "#testchan" and name != "BotName":
f.connection.sendData('IRC:'+' '.join(map(str, [name, msg])))
# This should make the bot send chat data to the distributor server (NOT IRC server)
请注意,我在这里给出的特定代码是一种非常粗糙的方法。它使用全局变量f
查找EchoFactory
实例。与大多数全局变量用法一样,这使得代码有点难以理解。此外,我还没有添加任何代码来处理connectionLost
事件以清除connection
属性。这意味着您可能认为您正在向分布式服务器发送数据,而连接已经丢失。同样,无法保证到分布式服务器的连接在IRC客户端首次尝试使用它时已经创建,因此当它尝试使用f.connection.sendData
时,您可能有一个AttributeError
然而,修复这些问题并不需要很大的飞跃。修复全局变量的用法,就像修复任何其他变量一样-通过向函数传递参数、将对象保存为其他对象上的引用等。通过处理它或在创建分布式连接之前不创建IRC连接来修复可能的
AttributeError
,等等,通过将属性值重置为None
或其他sentinel来处理丢失的连接,并在尝试使用分布式客户端连接发送任何数据之前注意IRC代码中的这种情况。我不知道这是否只是巧合,但是在sendData
中引发第一个错误的行没有正确缩进。@mac:我认为这与sendData
没有多大关系,但是这些函数不想以某种方式相互“通信”,因此它们可以将接收到的数据发送到与“活动”服务器不同的服务器谢谢!现在一切都清楚了,事实上,我在弄清楚之后,就成功了。
if channel == "#testchan" and name != "BotName":
f.connection.sendData('IRC:'+' '.join(map(str, [name, msg])))
# This should make the bot send chat data to the distributor server (NOT IRC server)