- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试为 IRC 库编写一个极其简单的界面,如下所示:
import simpleirc
connection = simpleirc.Connect('irc.freenode.net', 6667)
channel = connection.join('foo')
find_command = re.compile(r'google ([a-z]+)').findall
for msg in channel:
for t in find_command(msg):
channel.say("http://google.com/search?q=%s" % t)
从 their example 开始工作,我遇到麻烦了(代码有点长,所以我粘贴了它 here )。自从调用 channel.__next__
回调时需要返回<IRCClient instance>.privmsg
被称为,似乎没有一个干净的选择。使用异常或线程在这里似乎是错误的,是否有更简单(阻塞?)的使用扭曲的方式使这成为可能?
最佳答案
通常,如果您尝试以“阻塞”方式使用 Twisted,您将会遇到很多困难,因为这既不是它的预期使用方式,也不是大多数人使用的方式人们使用它。
顺其自然通常要容易得多,在这种情况下,这意味着接受回调。您问题的回调式解决方案如下所示:
import re
from twisted.internet import reactor, protocol
from twisted.words.protocols import irc
find_command = re.compile(r'google ([a-z]+)').findall
class Googler(irc.IRCClient):
def privmsg(self, user, channel, message):
for text in find_command(message):
self.say(channel, "http://google.com/search?q=%s" % (text,))
def connect():
cc = protocol.ClientCreator(reactor, Googler)
return cc.connectTCP(host, port)
def run(proto):
proto.join(channel)
def main():
d = connect()
d.addCallback(run)
reactor.run()
这不是绝对必需的(但我强烈建议您考虑尝试一下)。一种替代方法是 inlineCallbacks
:
import re
from twisted.internet import reactor, protocol, defer
from twisted.words.protocols import irc
find_command = re.compile(r'google ([a-z]+)').findall
class Googler(irc.IRCClient):
def privmsg(self, user, channel, message):
for text in find_command(message):
self.say(channel, "http://google.com/search?q=%s" % (text,))
@defer.inlineCallbacks
def run():
cc = protocol.ClientCreator(reactor, Googler)
proto = yield cc.connectTCP(host, port)
proto.join(channel)
def main():
run()
reactor.run()
不再注意 addCallbacks
。在经过修饰的生成器函数中,它已被替换为 yield
。如果您有一个带有不同 API 的 Googler
版本,这可能会更接近您的要求(上面的那个应该与 Twisted 的 IRCClient
一起工作,因为它是这样写的 -虽然我没有测试它)。 Googler.join
完全有可能返回某种类型的 Channel
对象,并且该 Channel
对象可以像这样迭代:
@defer.inlineCallbacks
def run():
cc = protocol.ClientCreator(reactor, Googler)
proto = yield cc.connectTCP(host, port)
channel = proto.join(channel)
for msg in channel:
msg = yield msg
for text in find_command(msg):
channel.say("http://google.com/search?q=%s" % (text,))
只需在现有的 API 之上实现此 API 即可。当然,yield
表达式仍然存在,我不知道这会让您多么不高兴。 ;)
可以进一步远离回调,并使异步操作所必需的上下文切换完全不可见。这很糟糕,原因与您家外的人行道上散落着看不见的捕熊器也很糟糕。然而,这是可能的。使用类似 corotwine 的东西,本身基于 CPython 的第三方协程库,您可以让 Channel
的实现自己进行上下文切换,而不是要求调用应用程序代码来执行它。结果可能类似于:
from corotwine import protocol
def run():
proto = Googler()
transport = protocol.gConnectTCP(host, port)
proto.makeConnection(transport)
channel = proto.join(channel)
for msg in channel:
for text in find_command(msg):
channel.say("http://google.com/search?q=%s" % (text,))
Channel
的实现可能类似于:
from corotwine import defer
class Channel(object):
def __init__(self, ircClient, name):
self.ircClient = ircClient
self.name = name
def __iter__(self):
while True:
d = self.ircClient.getNextMessage(self.name)
message = defer.blockOn(d)
yield message
这又取决于一个新的 Googler
方法,getNextMessage
,这是一个基于现有 IRCClient
回调的直接功能添加:
from twisted.internet import defer
class Googler(irc.IRCClient):
def connectionMade(self):
irc.IRCClient.connectionMade(self)
self._nextMessages = {}
def getNextMessage(self, channel):
if channel not in self._nextMessages:
self._nextMessages[channel] = defer.DeferredQueue()
return self._nextMessages[channel].get()
def privmsg(self, user, channel, message):
if channel not in self._nextMessages:
self._nextMessages[channel] = defer.DeferredQueue()
self._nextMessages[channel].put(message)
要运行它,您需要为 run
函数创建一个新的 greenlet 并切换到它,然后启动 reactor。
from greenlet import greenlet
def main():
greenlet(run).switch()
reactor.run()
当 run
开始它的第一个异步操作时,它会切换回 reactor greenlet(在本例中是“主要”greenlet,但这并不重要)让异步操作操作完成。当它完成时,corotwine 将回调转换为 greenlet 切换回 run
。所以 run
被赋予了直接运行的错觉,就像一个“正常”的同步程序。不过请记住,这只是一种错觉。
因此,您可以随心所欲地远离 Twisted 中最常用的面向回调的样式。不过,这不一定是个好主意。
关于python - 围绕 twisted 的 IRC 客户端编写一个阻塞包装器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2687656/
基于浏览器的 irc 客户端是否可以在不使用任何网关的情况下工作,即直接与 irc 服务器通信? 最佳答案 HTML5 WebSocket 无法连接到非 WebSocket 服务器。使用 WebSoc
已关闭。这个问题是 off-topic 。目前不接受答案。 想要改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 已关闭11 年前。 Improve th
在我的 IRC Bot 中,有一些命令我希望只能由我使用,并且我想检查以确保使用我的名字的任何人都被识别为 nickserv (idented)。但是,我无法找到一种简单的方法来确定这一点,这就是我在
我想在我的网站上实现聊天服务,想知道如何从头开始创建一个简单的基于浏览器的 IRC 客户端? 我有一个 linux box,可以在上面安装任何我想要的东西。 Google 找到了关于如何设置 IRC
我希望能够在不加入 IRC channel 的情况下从 IRC channel 获取用户列表及其详细信息,从而增加其用户数量。 所以不要发出 JOIN #chan然后 NAMES #chan要获取用户
关闭。这个问题是off-topic .它目前不接受答案。 想改善这个问题吗? Update the question所以它是 on-topic对于堆栈溢出。 8年前关闭。 Improve this q
我正在尝试编写我自己的 IRC 服务器。我引用的是 IRC RFC,但它让我有点困惑。如果我严格遵守 RFC,我认为任何流行的客户端都不会与我的服务器一起工作,比如 mIRC。例如,RFC 规定服务器
我正在使用标准库中的 TcpStream 开发一个 IRC 机器人。 我能够阅读输入的所有行,但 IRC 服务器似乎没有响应我的身份请求。我以为我发送请求的时间太早了,所以我尝试在发送 IDENT 之
我想连接到 ExIrc 中的两台服务器使用 Elixir ,我找不到一个简单的解决方案。我对 elixir 还很陌生,我能做的就是使用“伞”来运行两个应用程序并使它们相互连接? (我想用一个应用程序连
这个数字不是 RFC 1459 的一部分,但我希望能够使用它以便在 IRC 机器人中正确堆叠和取消堆叠模式。有没有不发送这个的主流 IRC 服务器? 最佳答案 这是规范的可选建议,这意味着编写客户端的
我对此进行了广泛的搜索,只找到了特定于机器人的客户端。我知道它们基本相同,但是对于我想做的事情,我就是想不通。 我正在尝试编写一个 python 客户端,它表面上是纯粹而简单的。例如,当从命令行运行时
我正在使用 net.Socket 模块连接到 EFNET 并测试我的代码,以便向我的机器人添加重新连接事件。 我可以通过哪些方式来模拟机器人断开连接?问题是 2-3 周后就会断开连接 - 我添加了事件
require "socket" server = "irc.rizon.net" port = "6667" nick = "Ruby IRC Bot" channel = "#0x40" s =
我正在尝试编写一个函数,使用 Twisted Python 将 IRC channel 中的昵称列表打印到该 channel 。我该怎么做呢?我已经阅读了 API 文档,并且在该站点上只看到一个与我的
我有一个命令,我想将其限制在某些级别。我正在使用 unreal3.2.6 IRC。 我读到这个: 但我仍然不确定我可以做些什么来检查用户排名。 我想看看用户是否是“语音”或更高级别。什么可以查找用户,
我正在计划建立一个 IRC 网络并一直在探索各种选择。我打算使用Inspircd IRC Server 。以及运行 meteor 的网络服务器。是否可以使用 websockets 构建一个 Web I
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 想改进这个问题?将问题更新为 on-topic对于堆栈溢出。 8年前关闭。 Improve this qu
如何获得 Weechat 配置变量?例如,我可以设置配置: /set irc.servers.freenode.ssl on 如何检索我设置的值? 最佳答案 要检查配置变量的值,您可以这样做: /se
有没有办法告诉irssi我要自动加入当前打开的所有 channel ? 我想要类似的东西: /channel add -auto /save 最佳答案 我找到了答案here: /alias adda
我整天都在搜寻Google,并且正在寻找一种方法来编写具有不同颜色的文本,就像我在其他IRC channel 上经常看到的那样。我想通过基于CLI的irssi实现此目的。我发现了多种无法正常工作的方法
我是一名优秀的程序员,十分优秀!