ejabberd收到客户端资源绑定请求时,会检测绑定的资源是否冲突(即检测是否已有账号绑定了该资源),并执行相应的动作,可选的执行动作包括:
(1) 不接受新的注册(closenew)
ejabberd对新注册的客户端回复error
<iq type='set' id='01'>
<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
<resource>boston</resource>
</bind>
</iq>
<iq type='error' id='01'>
<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
<resource>boston</resource>
</bind>
<error code='409' type='modify'>
<conflict xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq>
(2) 接受新的注册(acceptnew)
ejabberd对老的账号,即已经绑定该资源的账号回复error,并断开连接
<error xmlns='http://etherx.jabber.org/streams'>
<conflict xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>
<text xmlns='urn:ietf:params:xml:ns:xmpp-streams' lang=''>
Replaced by new connection
</text>
</error>
(3) 接受新的注册并重置其资源名(setresource)
<iq type='set' id='01'>
<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
<resource>boston</resource>
</bind>
</iq>
<iq id='01' type='result'>
<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
<jid>rondo@nba.com/27193913371362104918759722</jid>
</bind>
</iq>
ejabberd默认的动作是接受新的注册,但是可以在配置文件ejabberd.cfg中对其进行配置
{resource_conflict, Action}.
Action的值为 closenew/closeold/acceptnew/setresource
这里需要注意的是:ejabberd会记录客户端登陆的时间,并在资源绑定检测时,根据登录时间排序然后按照上述方式进行相应的处理;如果采用了集群加负载均衡的方式,并且集群中ejabberd所在服务器的时间有不一致,那么会出现很多奇怪的问题(例如:A,B两台ejabberd形成集群,前面配置了haproxy作负载均衡 ,A服务器的时间比B服务器的时间快很多,第一个客户端通过负载均衡登陆到A服务器上,过一段时间,第二个客户端(同账号绑定相同资源)通过负载均衡登陆到B服务器上, 结果第二个客户端收到了Replaced by new connection的error消息)。