Вход в единый запрос Ejabberd

У меня есть работающий сервер Ejabberd (версия 2.1.9) и мое клиентское приложение работает нормально, но я хочу изменить способ подключения XMPP-клиента приложения к Ejabberd, чтобы уменьшить количество запросов/ответов между ними, потому что это для мобильная среда, и я хочу сократить начальное время соединения.

Я просмотрел спецификацию протокола XMPP (RFC 6120) и некоторые расширения протокола (XEP), а именно Быстрый запуск XEP-0305, но сам протокол не определяет вход с одним запросом и расширение Quickstart, хотя и направлено на сокращение количества запросов, недостаточно для сокращения времени, которое я ищу.

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

//Client Request
<?xml version='1.0'?>
<stream:stream ... user='user' pass='pass'>

//Server Response
<?xml version='1.0'?>
<stream:stream ... success='1'>

Мне удалось соответствующим образом изменить мой клиент и сервер Ejabberd, и кажется, что они успешно подключаются, но любой запрос, который делает клиент после установления сеанса, не получает ответа от сервера. Я использовал Wireshark для проверки TCP-соединения на стороне клиента и сервера: на стороне клиента он открыт, и запрос отправляется, а на стороне сервера также открыт, и запрос получен, но когда я пытаюсь отправить ответ, это не так. послал.

Я изменил ТОЛЬКО файл ejabberd_c2s.erl, и изменения следующие:

//init function
...
%% changed the first state of the fsm to point to quickstart
%%          {ok, wait_for_stream, #state{socket = Socket1,
            {ok, wait_for_quickstart, #state{socket = Socket1,
...

//wait_for_quickstart function
...
case resource_conflict_action(U, StateData#state.server, R) of
  closenew ->
    send_header(StateData, Server, "1.0", DefaultLang, "0"),
    send_trailer(StateData),
    {stop, normal, StateData};
    {accept_resource, R2} ->
      JID = jlib:make_jid(U, StateData#state.server, R2),
      allow = acl:match_rule(Server,c2s,JID),   
      case ejabberd_auth:check_password(U, Server, P) of
        true ->
          send_header(StateData, Server, "1.0", DefaultLang, "1"),
          change_shaper(StateData, JID),
          {Fs, Ts} = ejabberd_hooks:run_fold(
            roster_get_subscription_lists,
            StateData#state.server,
            {[], []},
            [U, StateData#state.server]),
          LJID = jlib:jid_tolower(jlib:jid_remove_resource(JID)),
          Fs1 = [LJID | Fs],
          Ts1 = [LJID | Ts],
          PrivList =
            ejabberd_hooks:run_fold(
            privacy_get_user_list, 
            StateData#state.server,
            #userlist{},
           [U, StateData#state.server]),
         SID = {now(), self()},
         Conn = get_conn_type(StateData),
         Info = [{ip, StateData#state.ip},
         {conn, Conn},
         {auth_module, StateData#state.auth_module}],
         ejabberd_sm:open_session(SID, U, StateData#state.server, R, Info),
         NewStateData =
           StateData#state{
             user = U,
             resource = R2,
             jid = JID,
             sid = SID,
             conn = Conn,
             auth_module = ejabberd_auth_internal,
             authenticated = true,
             pres_f = ?SETS:from_list(Fs1),
             pres_t = ?SETS:from_list(Ts1),
             privacy_list = PrivList},
           fsm_next_state_pack(session_established,
           NewStateData);
        _ ->
          %%auth fail
          end
end.

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

Я что-то упускаю из виду?

заранее спасибо


person ZeCodea    schedule 15.12.2011    source источник
comment
Кажется, у вас могут быть проблемы с маршрутизацией. Вы создаете ресурс или пользователь должен его отправить? Вы не указали это выше. Обычно это делается в операции привязки, но, поскольку вы пропустили ее, возможно, поэтому она не работает.   -  person Nuno Freitas    schedule 15.12.2011


Ответы (1)


@Nuno-Freitas Нуно-Фрейтас Действительно, это было ошибкой, спасибо за вашу полезную информацию.

Я добавил код:

R1 = xml:get_attr_s("r",Attrs),
R = case jlib:resourceprep(R1) of
      error -> error;
      "" ->
        lists:concat([randoms:get_string() | tuple_to_list(now())]);
        Resource -> Resource
    end,

Это заставило сервер отвечать на мои запросы, но было другое: тег <presence/> ломался на сервере, потому что #state.lang не был определен, поэтому мне пришлось определить его в функции wait_for_quickstart, и теперь у меня есть единый вход в клиенте XMPP. рабочее доказательство концепции сервера.

person ZeCodea    schedule 16.12.2011