【问题标题】:Twisted deferred variable from another source来自另一个来源的扭曲延迟变量
【发布时间】:2015-12-25 01:55:03
【问题描述】:

我正在运行一个 IRC 机器人,我终于弄清楚了如何通过 whois 正确获取用户的身份验证。我现在希望实现此检查以引用我的数据库,而不是依赖他们的用户名。

我有一个命令

def privmsg(self, user, channel, msg):
    if msg.startswith(".join"):
        # sends whois signal
        irc.IRCClient.whois(self, user, None)

我需要从被输出源(IRC 服务器)调用的函数中获取变量,因此我不能只添加回调

        auth = ???
        player = db.getplayer(auth)

我正在通过

接收身份验证
def irc_330(self, prefix, params):
    auth = params[2]

我似乎无法弄清楚如何将变量准确地发送回第一个函数,甚至无法确定如何等待该信号返回。我的第一个函数会在 irc_330() 开始之前传递任何东西。

我能想到的唯一解决方案是创建一个回调函数,该函数将等待其中的函数调用,然后返回我需要的内容。但这似乎根本不对。

【问题讨论】:

    标签: python twisted deferred


    【解决方案1】:

    您在这里遇到的问题是IRCClient 的 API 相当 糟糕的(对不起!)。具体来说,它有像.whois() 这样的API 应该返回Deferred,但不要。

    您可以通过制作这些 API 的自己的版本来解决此问题, 事实上,返回一个Deferred

    一般的想法是 IRC 请求和响应没有请求 ID,所以 他们总是按顺序回答。这意味着你需要建立一个队列 先进/先出请求,以便您可以将它们与回复相匹配作为回复 到达。此外,您需要将延迟触发与查询的 end 相匹配 (在您的情况下是 WHOIS,因此是 RPL_ENDOFWHOIS),因为 IRC 服务器可能 或者可能不发送特定字段作为响应的一部分。

    这是一个实现的示例:

    from collections import deque
    from twisted.internet.defer import Deferred
    from twisted.words.protocols.irc import IRCClient
    
    class NoAccount(Exception):
        "No account found."
    
    class MyClient(IRCClient, object):
    
        def __init__(self):
            self._whoisQueue = deque()
    
        def deferredWhois(self, nick):
            result = Deferred()
            self._whoisQueue.append((result, nick))
            self.whois(nick)
            return result
    
        def irc_330(self, prefix, params):
            self._currentActiveNick = params[2]
    
        def irc_RPL_ENDOFWHOIS(self, prefix, params):
            deferredToFire, who = self._whoisQueue.popleft()
            currentActiveNick = self._currentActiveNick
            self._currentActiveNick = None
    
            if currentActiveNick is None:
                deferredToFire.errback(NoAccount(who))
            else:
                deferredToFire.callback(currentActiveNick)
    

    这使得deferredWhois 方法返回一个Deferred 给定昵称的帐户名。

    希望这会有所帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-20
      • 2014-07-13
      相关资源
      最近更新 更多