2011-12-15 69 views
2

我有一個工作的Ejabberd服務器(版本2.1.9),我的客戶端應用程序運行良好,但我希望修改應用程序的XMPP客戶端連接到Ejabberd的方式以減少請求數/它們之間的響應,因爲它適用於移動環境,我希望減少初始連接時間。Ejabberd單一請求登錄

我查了XMPP協議規範(RFC 6120)和一些協議擴展(XEPs),即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. 

只是爲了澄清:初始客戶端認證請求和服務器響應被傳輸就好了,後續的請求也被傳播,但沒有迴應。

我是我俯視的東西?

在此先感謝

+1

看起來你可能有一些路由問題。您是生成資源,還是用戶必須發送它?你沒有在上面指定。通常它是在綁定操作中完成的,但是因爲你跳過了它,這可能是它失敗的原因。 – 2011-12-15 19:03:26

回答

1

@努諾 - 弗雷塔斯事實上,這是發生了什麼故障,感謝您的有益的見解。

我加了碼:

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客戶端服務器的工作概念證明。