了解 ejabberd filter_packet 钩子参数

Understanding ejabberd filter_packet hook parameters

我正在尝试使用 Smack 和 ejabberd 实现聊天消息传递应用程序。我在服务器上的 filter_packet 挂钩中将以下输入作为 Packet 参数:

   {{jid,<<"senderUserName">>,<<"domain.com">>,<<"Smack">>,<<"senderUserName">>,<<"domain.com">>,<<"Smack">>},{jid,<<"receiverUserName">>,<<"domain.com">>,<<>>,<<"receiverUserName">>,<<"domain.com">>,<<>>},{xmlel,<<"message">>,[{<<"xml:lang">>,<<"en">>},{<<"to">>,<<"receiverUserName@domain.com">>},{<<"id">>,<<"4Xd7d-13">>},{<<"type">>,<<"chat">>}],[{xmlel,<<"body">>,[],[{xmlcdata,<<"my message">>}]},{xmlel,<<"thread">>,[],[{xmlcdata,<<"25e5fc87-e57f-4046-9aef-30c569ab9160">>}]},{xmlel,<<"customTag">>,[],[{xmlcdata,<<"Custom extras">>}]}]}}

这是我的问题:

  1. 为什么我收到两次发件人和收件人用户名?
  2. 如何获取 Erlang 中不同元组元素的值?

ejabberd filter_packet 钩子参数是一个包含以下值的元组:{FromJID, ToJID, XMLPacket}.

  • FromJID 是一条 #jid{} 记录。
  • ToJID 是 #jid{}.
  • XML数据包是一个 #xmlel{} 记录,它是原始 XMPP 数据包的解析表示。

您的第一个问题是关于 #jid{} 记录结构(从和到)。内部记录不打算直接使用,而是通过 jlib.erl 函数使用。然而,目前,该记录确实进行了优化,以避免对 namepreped、nodepreped 用户名和域进行额外处理和匹配。 namepreped / nodepreped 值存储为原始未触及值的附加值。如果处理后的值等于原始值,是的,您可能会觉得这是重复的。但是,如果您使用各种大小写和一些特殊的 unicode 字符,情况会有所不同。

我想你的第二个问题是关于解析的 XML 元素数据结构。要从#xmlel 记录中提取和操作数据,您可以提取所需的记录字段:name、attrs 和 children。

记录定义为:

-record(xmlel, {
    name = <<"">> :: binary(),
    attrs    = [] :: [attr()],
    children = [] :: [xmlel() | cdata()] }).

您可以使用该信息在 XML 树中使用子列表。 您还可以在 xml.erl 模块中找到现成的辅助函数。