与 IRC 客户端通信

与客户端通信是 IRC 服务器的全部意义,因此您需要确保正确执行此操作。今天,我们将探讨如何接收来自客户端的消息以及如何向客户端发送消息。

在 Twisted 中表示客户端

Twisted IRC 中的用户表示为 the IRC class 的子类。这适用于您的 Factory 类协议。它还将为您提供 IRC 功能(例如自动解析传入行),而无需您自己实现它们。本指南的其余部分假设此设置。

发送消息

使用用户对象的 sendMessage 方法向用户发送消息。

发送基本消息

向用户发送消息的基本语法如下

user.sendCommand("COMMAND", (param1, param2), server.name)

prefix 关键字参数是可选的,可以省略它来发送没有前缀的消息(例如,ERROR 命令)。命令是您计划发送的任何命令,例如“PRIVMSG”、“MODE”等。命令后面的所有参数都是您要为命令发送的参数。如果最后一个参数需要以冒号开头(因为它包含空格,例如 PRIVMSG 消息),您必须自己将冒号添加到参数的开头。例如:.. code-block:: python

user.sendCommand(“PRIVMSG”, (user.nickname, “:{}”.format(message)), sendingUser.hostmask)

发送带标签的消息

Twisted 还允许发送 IRCv3 中指定的 message tags。

例如,假设您的服务器具有在有人加入频道时播放一小段先前频道内容的功能。您需要一种方法来告诉人们此消息发生的时间。提供此信息的最佳方法是通过 server-time 规范

假设您将过去的邮件存储在频道对象中,类似于以下结构

channel.pastMessages = [
    ("I sent some text!", "author!ident@host", datetime object representing the when the message was sent),
    ("I did, too!", "someone-else!ident@host", another datetime object)
]

您的实际实现可能有所不同。我在这里使用了简单的方法。消息的时间将使用类似于 datetime.utcnow() 的方法在接收消息时生成。

标签作为元组列表传递。如果您要发送多个标签,您可能拥有现有的标签字典。您可以简单地将其添加到其中(假设 message 是上面 channel.pastMessages 的循环变量)

sendingTags["server-time"] = "{}Z".format(message[2].isoformat()[:-3])

这将生成所需的时间格式并将其添加到标签字典中。我们删除的最后三个字符是微秒;删除最后三位数字将精度更改为毫秒。

收集完标签后,您可以发送消息。标签字典使用 tags 参数传递(在上面的循环中)

user.sendCommand("PRIVMSG", (user.nickname, message[0]), message[1], sendingTags)

接收消息

Twisted Words 将处理接收消息并将行解析为标记。解析后的消息通过用户的 handleCommand 方法传递到您的命令中。

处理命令

默认的 IRC handleCommand 方法在收到命令 COMMAND 时调用 irc_COMMAND 方法,如果未定义接收到的命令的方法,则调用 irc_unknown。

from twisted.words.protocols import irc

class IRCUser(irc.IRC):
    # possibly other definitions here
    def irc_unknown(self, prefix, command, params):
        self.sendCommand(irc.ERR_UNKNOWNCOMMAND, (command, ":Unknown command"), server.name)

    def irc_PRIVMSG(self, prefix, params):
        # do some stuff to handle PRIVMSG for your server's setup

    # lots of other command definitions

如果您有一个不允许您执行此操作的服务器设置(例如模块化服务器程序),您当然可以覆盖 handleCommand 函数以将命令路由到您自己的处理程序。

接收带标签的消息

这尚未实现。