我正在开发一个实时聊天应用。经过一段时间的搜索,我发现Ejabberd和Erlang是个不错的选择。
问题是Ejabberd没有提供我需要的所有功能。我需要一些自定义功能,如基于位置的匹配和匿名登录。
那么如何在Ejabberd之上开发自定义功能呢?为它写模块?或开发另一个独立的服务器应用程序(网络或其他类型的服务器应用程序)与它进行交互?
更新:另一个问题是我们添加自定义功能/功能的方式应该是可扩展的。
答案 0 :(得分:5)
您可以编写与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
答案 1 :(得分:3)
这是一个关于如何实现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)