如何在 Ejabberd 之上开发自定义函数?

Posted

技术标签:

【中文标题】如何在 Ejabberd 之上开发自定义函数?【英文标题】:How to develop custom functions on top of Ejabberd? 【发布时间】:2014-04-07 05:40:48 【问题描述】:

我正在开发一个实时聊天应用程序。找了一会,发现Ejabberd和Erlang是不错的选择。

问题是 Ejabberd 没有提供我需要的所有功能。我需要一些自定义功能,例如基于位置的匹配和匿名登录。

那么如何在 Ejabberd 之上开发自定义函数呢?为它写模块?还是开发另一个独立的服务器应用程序(Web 或其他类型的服务器应用程序)与之交互?

更新:另一个问题是我们添加自定义函数/特性的方式应该是可扩展的。

【问题讨论】:

Ejabberd 非常适合聊天和实时通知。但是,您提到的其他功能可以在另一个标准服务器中更轻松地实现。 @KeewonSeo 是的,你是对的。但是标准服务器如何与 Ejabberd 服务器通信呢? 对于独立(标准是错字...)服务器和 ejabberd 之间的交互,您可以写下自定义模块,正如其他答案所建议的那样。我忘了提。 【参考方案1】:

您可以编写与 ejabberd 中的事件挂钩的自定义模块。

这里是 ejabberd 的事件列表:

adhoc_local_items(Acc, From, To, Lang) -> Adhoc
adhoc_sm_items(Acc, From, To, Lang) -> Adhoc
c2s_stream_features(Acc)
c2s_unauthenticated_iq(Acc, Server, IQ) -> Packet
disco_local_features(Acc, From, To, Node, Lang) -> Adhoc
disco_local_identity(Acc, From, To, Node, Lang) -> Adhoc
disco_local_items(Acc, From, To, Node, Lang) -> Adhoc
disco_sm_features(Acc, From, To, Node, Lang) -> Adhoc
disco_sm_identity(Acc, From, To, Node, Lang) -> Adhoc
disco_sm_items(Acc, From, To, Node, Lang) -> Adhoc
ejabberd_ctl_process(Args) -> CtlStatus
filter_packet(From, To, Packet) -> From, To, Packet
local_send_to_resource_hook(From, To, Packet) -> ok
offline_message_hook(From, To, Packet) -> ok
privacy_check_packet(Acc, User, Server, PrivacyList, From, To, Packet, Dir) -> Auth
privacy_get_user_list(Acc, User, Server) -> PrivacyList
privacy_iq_get(Acc, From, To, IQ, ActiveList) -> result, Packet | error, Error
privacy_iq_set(Acc, From, To, IQ) -> result, Packet | error, Error
privacy_updated_list(Acc, OldPrivacyList, NewPrivacyList) -> PrivacyList
pubsub_publish_item(Host, Node, From, To, ItemId, Payload) -> ok
remove_user(User, Server) -> ok
resend_offline_messages_hook(Acc, User, Server) -> [Route]
resend_subscription_requests_hook(Acc, User, Server) -> [Packet]
roster_get(Acc, User, Server) -> [RosterItem]
roster_get_jid_info(Acc, User, Server, JID) -> Subscription, Groups
roster_get_subscription_lists(Acc, User, Server) -> [FromSubscription],[ToSubscription]
roster_in_subscription(Acc, User, Server, JID, SubscriptionType, Reason) -> bool()
roster_out_subscription(Acc, User, Server, JID, SubscriptionType, Reason) -> bool()
roster_process_item(RosterItem, Server) -> RosterItem
sm_register_connection_hook(SID, JID, Info) -> ok
sm_remove_connection_hook(SID, JID, Info) -> ok
unset_presence_hook(User, Server, Resource, Status) -> void()
user_available_hook(JID) -> ok
user_receive_packet(JID, From, To, Packet) -> ok
user_send_packet(From, To, Packet) -> ok

http://www.ejabberd.im/Events+and+hooks

这是一个关于如何为 ejabberd 创建模块的教程: http://happy.cat/blog/XMPP-Bots-ejabberd-mod-motion-2010-02-01-10-00.html

基本上编写一些模块并在 ejabberd.cfg 配置文件中注册/添加您的模块,如下所示(例如“mod_motion”):

 modules,

 [

  %% ....

  mod_motion,  [],

  %% ....

 ]

我开发的一个例子可以在这里找到: https://github.com/Mingism/ejabberd-stanza-ack

【讨论】:

【参考方案2】:

这是一个很好的例子,说明如何实现 Ejabberd 的基于状态的模块。

http://metajack.im/2008/08/28/writing-ejabberd-modules-presence-storms/

一些亮点:

挂钩您的活动

在本例中,作者选择在 Ejabberd 上挂钩存在

start(Host, _Opts) ->
    ejabberd_hooks:add(set_presence_hook, Host, ?MODULE, on_presence, 50),
    ok.

ejabberd_hooks:add的格式为:

ejabberd_hooks:add(Hook, Host, Module, Function, Priority)

所以你只需要像这样实现Function(第四个参数):

on_presence(_User, _Server, _Resource, _Packet) ->
    none.

所有钩子的完整列表:https://www.process-one.net/en/wiki/ejabberd_events_and_hooks/

解析选项

如果您想让您的模块具有可扩展性,您需要定义一些变量以便您轻松更改它。

您可以使用gen_mod:get_module_opt(Host, Module, Opt, Default) 在您的ejabberd.cfg 中获取选项

例如,如果您的配置如下所示:

mod_sunshine, [count, 20, interval, 60]

您可以通过以下方式获取count

gen_mod:get_module_opt(Server, ?MODULE, count, 10)

【讨论】:

以上是关于如何在 Ejabberd 之上开发自定义函数?的主要内容,如果未能解决你的问题,请参考以下文章

LayUi创建一个自定义通用模块

自定义 Ejabberd

在 ejabberd 中编译新的自定义模块时出错

Ejabberd - 为自定义命令运行 SQL 查询

R语言用户自定义函数的语法结构编写自定义统计值计算函数(使用ifelse结构计算均值和标准差等)编写自定义日期格式化(format)函数(switch函数使用不同分枝格式化日期数据)应用自定函数

ejabberd - 自定义 iq 处理程序