2011-12-15 102 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客户端服务器的工作概念证明。