From 9a03e5087e483119cf6965fa848c84d72282a0b6 Mon Sep 17 00:00:00 2001 From: Badlop Date: Mon, 26 Nov 2007 10:15:18 +0000 Subject: [PATCH] * src/mod_echo.erl: Example function that demonstrates how to receive XMPP packets using Erlang's message passing mechanism (EJAB-247). SVN Revision: 980 --- ChangeLog | 2 ++ src/mod_echo.erl | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/ChangeLog b/ChangeLog index c6a2b8e61..4558b7b9a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2007-11-26 Badlop + * src/mod_echo.erl: Example function that demonstrates how to receive XMPP packets using Erlang's message passing mechanism (EJAB-247). + * src/ejabberdctl.template: Removed bashisms (EJAB-399). Set environment variables instead of passing parameters when calling erl (EJAB-421). Write erl_crash.dump in the log/ directory, with unique filename (EJAB-433). * src/ejabberd_ctl.erl: Improvements in the help messages (EJAB-399). diff --git a/src/mod_echo.erl b/src/mod_echo.erl index b75929958..050677304 100644 --- a/src/mod_echo.erl +++ b/src/mod_echo.erl @@ -102,6 +102,7 @@ handle_info({route, From, To, Packet}, State) -> "" -> jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST); _ -> Packet end, + do_client_version(To, From), ejabberd_router:route(To, From, Packet2), {noreply, State}; handle_info(_Info, State) -> @@ -128,3 +129,50 @@ code_change(_OldVsn, State, _Extra) -> %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- + +%% ejabberd provides a method to receive XMPP packets using Erlang's +%% message passing mechanism. +%% +%% The packets received by ejabberd are sent +%% to the local destination process by sending an Erlang message. +%% This means that you can receive XMPP stanzas in an Erlang process +%% using Erlang's Receive, as long as this process is registered in +%% ejabberd as the process which handles the destination JID. +%% +%% This example function is called when a client queries the echo service. +%% This function then sends a query to the client, and waits 5 seconds to +%% receive an answer. The answer will only be accepted if it was sent +%% using exactly the same JID. We add a (mostly) random resource to +%% try to guarantee that the received response matches the request sent. +%% Finally, the received response is printed in the ejabberd log file. +do_client_version(From, To) -> + ToS = jlib:jid_to_string(To), + %% It is important to identify this process and packet + Random_resource = integer_to_list(random:uniform(100000)), + From2 = From#jid{resource = Random_resource, + lresource = Random_resource}, + + %% Build an iq:query request + Packet = {xmlelement, "iq", + [{"to", ToS}, {"type", "get"}], + [{xmlelement, "query", [{"xmlns", ?NS_VERSION}], []}]}, + + %% Send the request + ejabberd_router:route(From2, To, Packet), + + %% Wait to receive the response + %% It is very important to only accept a packet which is the + %% response to the request that he sent + Els = receive {route, To, From2, IQ} -> + {xmlelement, "query", _, List} = xml:get_subtag(IQ, "query"), + List + after 5000 -> % Timeout in miliseconds: 5 seconds + [] + end, + Values = [{Name, Value} || {xmlelement,Name,[],[{xmlcdata,Value}]} <- Els], + + %% Print in log + Values_string1 = [io_lib:format("~n~s: ~p", [N, V]) || {N, V} <- Values], + Values_string2 = lists:concat(Values_string1), + ?INFO_MSG("Information of the client: ~s~s", [ToS, Values_string2]). +