客户端资源绑定
当客户端身份验证成功后,服务器端features中指定需要BIND资源,则客户端发送bind请求。
client->c2s:
<iq type="set" id="32"><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"><resource>Gajim</resource></bind></iq>
当收到服务器的stream:features中包含了<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'><required></bind>后,说明服务器必须要求客户端BIND资源。
客户端同样必须发送一个符合'urn:ietf:params:xml:ns:xmpp-bind'名字空间的'set'类型的IQ节给服务器绑定一个资源到流中。客户端也可以不指定资源ID,而由服务器自动生成,也可以自己生成一个资源ID,但服务器有权利选择是否使用客户端自己生成的。
这条消息最终执行到函数_c2s_client_sx_callback(sx_event_t = event_PACKET)
在case event_PACKET中有这样的判断:
if((ns = nad_find_scoped_namespace(nad, uri_BIND, NULL)) >= 0 &&
(elem = nad_find_elem(nad, 0, ns, "bind", 1)) >= 0 &&
nad_find_attr(nad, 0, -1, "type", "set") >= 0)
符合这个判断,执行if里的代码, 服务器选择使用用户自定义的资源ID或者生成资源ID,
然后必须返回一个'result'类型的IQ节给客户端,这个节必须包含一个指明全JID的</jid>子元素表示服务器决定连接的资源。
调用sm_start函数,构造一个发送给router的协议:
c2s->router:
<route xmlns='http://jabberd.jabberstudio.org/ns/component/1.0' from='c2s' to='easyjabberd.com'><sc:session xmlns:sc='http://jabberd.jabberstudio.org/ns/session/1.0' id='656be3f310b717525c441e1335345bde0232b00a' target='zhanghua@easyjabberd.com/Gajim' action='start' sc:c2s='8'/></route>
这里忽略对router的分析,针对router程序我会专门在新的文章中分析。
router->c2s:
<route xmlns='http://jabberd.jabberstudio.org/ns/component/1.0' to='c2s' from='sm'><sc:session xmlns:sc='http://jabberd.jabberstudio.org/ns/session/1.0' sc:c2s='8' action='started' target='zhanghua@easyjabberd.com/Gajim' id='656be3f310b717525c441e1335345bde0232b00a' sc:sm='f88d031a7954dc9cb162670c53a5c942b27034c1'/></route>
由于是router发回来的数据,会调用c2s_router_sx_callback函数
在case event_PACKET中if(strncmp("started", NAD_AVAL(nad, action), 7) == 0)的判断,执行这里的代码。
在sm_start函数之前的时候,c2s在处理客户端发送的bind请求的时候,已经构造好了返回的result的iq节。但当时没有发送,就是等待router发送started后发送。
c2s->client:
<iq xmlns='jabber:client' id='32' type='result'><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'><jid>zhanghua@easyjabberd.com/Gajim</jid></bind></iq>