Nano Hash - криптовалюты, майнинг, программирование

Модуль MongooseIM не получает переменные из пакета

Я написал следующий модуль для MongooseIM, но в файле PHP ничего не публикуется.

start(_Host, _Opt) -> 
    inets:start(),
    ejabberd_hooks:add(user_send_packet, _Host, ?MODULE, fetchPacketData, 50).
stop (_Host) -> 
    ejabberd_hooks:delete(user_send_packet, _Host, ?MODULE, fetchPacketData, 50).
fetchPacketData(_From, _To, Packet) ->
    To = xml:get_tag_attr_s(<<"to">>, Packet),
    httpc:request(post, {"http://example.com/receiver.php",[],
            "application/x-www-form-urlencoded",
            lists:concat(["To=",To,"&Type=1","&Body=ABC"])}, [], []).

Мне удалось успешно внедрить модуль после того, как я последовал предложению erszcz (см. ниже). Ниже приведен код, который я использовал. Надеюсь, это поможет кому-то еще :)

start(Host, _Opts)->
  inets:start(),
  ejabberd_hooks:add(user_send_packet, Host, ?MODULE, sendMessage, 50),
  ok.
stop(Host)->
  ejabberd_hooks:delete(user_send_packet, Host, ?MODULE, sendMessage, 50),
  ok.
sendMessage(_From, _To, Packet) ->
  case xml:get_tag_attr_s(<<"type">>, Packet) of
    <<"chat">> ->
      To = lists:flatten(io_lib:format("~s", [xml:get_tag_attr_s(<<"to">>, Packet)])),
      ** post variables to PHP file using httpc:request **
      ok;
    _ ->
      ok
    end.

Ответы:


1

offline_message_hook вызывается только тогда, когда сервер перенаправляет сообщение пользователю, который не находится в сети. user_send_packet запускается каждый раз, когда сервер получает раздел от клиента. Это может объяснить, почему обработчик не запускается, хотя это зависит от того, как вы тестируете. Есть статья с одним разделом, описывающим некоторые хуки в MongooseIM доступен на официальной вики.

Что касается проблем с получением атрибутов пакета, то либо регистрация входящего пакета для проверки, либо использование dbg в оболочке Erlang сервера для отслеживания фактических вызовов, выполняемых вашим модулем, может быть способом определить, что происходит.


Пример сеанса с dbg отладкой проблемы может выглядеть так:

(mongooseim@localhost)1> dbg:tracer().
{ok,<0.570.0>}
(mongooseim@localhost)2> dbg:p(all, call).
{ok,[{matched,mongooseim@localhost,279}]}
(mongooseim@localhost)3> dbg:tpl(mod_test, x).
{ok,[{matched,mongooseim@localhost,5},{saved,x}]}
(mongooseim@localhost)4> (<0.576.0>) call mod_test:fetchPacketData({jid,<<"alice">>,<<"localhost">>,<<"escalus-default-resource">>,<<"alice">>,
     <<"localhost">>,<<"escalus-default-resource">>},{jid,<<"alice">>,<<"localhost">>,<<>>,<<"alice">>,<<"localhost">>,<<>>},{xmlel,<<"presence">>,[{<<"xml:lang">>,<<"en">>}],[]})
(<0.576.0>) exception_from {mod_test,fetchPacketData,3} {error,function_clause}
2015-03-15 11:46:03.028 [error] <0.576.0>@ejabberd_hooks:run1:240 {function_clause,[{lists,thing_to_list,[<<>>],[{file,"lists.erl"},{line,601}]},{lists,flatmap,2,[{file,"lists.erl"},{line,1248}]},{lists,flatmap,2,[{file,"lists.erl"},{line,1248}]},{mod_test,fetchPacketData,3,[{file,"src/mod_test.erl"},{line,15}]},{safely,apply,3,[{file,"src/safely.erl"},{line,19}]},{ejabberd_hooks,run1,3,[{file,"src/ejabberd_hooks.erl"},{line,236}]},{ejabberd_c2s,session_established2,2,[{file,"src/ejabberd_c2s.erl"},{line,1063}]},{p1_fsm_old,handle_msg,10,[{file,"src/p1_fsm_old.erl"},{line,542}]}]}
    Running hook: {user_send_packet,[{jid,<<"alice">>,<<"localhost">>,<<"escalus-default-resource">>,<<"alice">>,<<"localhost">>,<<"escalus-default-resource">>},{jid,<<"alice">>,<<"localhost">>,<<>>,<<"alice">>,<<"localhost">>,<<>>},{xmlel,<<"presence">>,[{<<"xml:lang">>,<<"en">>}],[]}]} 
    Callback: mod_test:fetchPacketData

Мы видим, что обработчик выдает ошибку function_clause при вызове lists:thing_to_list(<<>>). Пустой двоичный файл является результатом xml:get_tag_attr_s/2, когда запрошенный атрибут не найден. lists:thing_to_list/1 вызывается для преобразования каждого параметра lists:concat/1 в список, но невозможно преобразовать пустой двоичный файл <<>> в список, отсюда и сбой.

Сопоставьте результат xml:get_tag_attr_s/2 и создайте свою логику соответственно каждому случаю: когда атрибут найден и когда его нет.


Я не знаю, как запустить модуль в dbg. Я попробовал то, что вы поделились выше, и я думаю, что вы пропустили 4-ю команду, которая может быть примером того, как инициировать модуль.

Это сырой дамп моей консоли без каких-либо правок - я не пропустил ни одной части. Вы не «запускаете модуль в dbg». Вы просто запускаете модуль обычным способом, а затем используете dbg из оболочки сервера.

Я взял код вашего примера, поместил его в файл apps/ejabberd/src/mod_test.erl и создал релиз. После этого вы можете включить модуль либо в ejabberd.cfg релиза (ищите раздел modules и сделайте это аналогично тому, как показано в примерах), либо вы можете запустить сервер в режиме реального времени с помощью mongooseimctl live и запустить модуль вручную с помощью gen_mod:start_module(<<"localhost">>, mod_test, []) (где <<"localhost">> просто пример домена XMPP - подставьте туда свой подходящий домен).

Когда модуль работает (можно проверить с помощью gen_mod:is_loaded(<<"your-xmpp-domain">>, mod_name_goes_here)), вы должны включить dbg. Это показано в списке, который я добавил ранее. Я не буду вдаваться в описание того, как использовать dbg, так как очень хорошее введение уже доступно на Переполнение стека.


пример того, как проверить, существует ли атрибут или нет

case xml:get_tag_attr_s(<<"some-attribute">>, Packet) of
    <<>> ->
        %% attribute does not exist, as get_tag_attr_s returned the default value
        ok;
    <<"some-value">> ->
        %% do something sensible with <<"some-value">>
        ok
end

В качестве альтернативы вы можете использовать exml, который также является частью MongooseIM (но не оригинального ejabberd) и более явно указывает на то, что вы не можете найти запрашиваемый атрибут:

case exml_query:attr(Packet, <<"some-attribute">>) of
    undefined ->
        %% not found
        ok;
    <<"some-value">> ->
        %% do something
        ...
end
15.03.2015
  • спасибо эрщ. Я пробовал dbg, но не смог решить проблему. Могу ли я отправить пакет как есть в файл PHP и проверить через PHP, что не так? (я пробовал это, но ничего не было отправлено в PHP) 15.03.2015
  • Код, который у вас есть, теперь имеет ошибку, которая приводит к сбою вашей функции, и httpc:request никогда не вызывается - я описал ошибку выше. Вы можете опубликовать весь пакет в приложении PHP, но вы должны заранее сериализовать его в строку. Почему ваша сессия dbg не была успешной? 15.03.2015
  • я не знаю, как запустить модуль в dbg. я попробовал то, что вы поделились выше, и я думаю, что вы пропустили 4-ю команду, которая может быть примером того, как инициировать модуль. 16.03.2015
  • также, если бы вы могли показать пример того, как проверить, существует ли атрибут или нет. 16.03.2015
  • Я отредактировал исходный ответ на ваши вопросы. 16.03.2015
  • спасибо erszcz за подробное объяснение. я успешно реализовал тест, чтобы проверить, существуют ли атрибуты или нет. Кроме того, я использовал приведенный ниже метод для преобразования значений в строку, а затем отправил его в PHP, и он работает нормально. To = lists:flatten(io_lib:format(~s, [xml:get_tag_attr_s(‹‹to››, Packet)])). Большое спасибо за помощь. :) 17.03.2015
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..