XMPP over HTTP是定义在XEP-0124里的扩展。它的原理是把XML stream头替换成HTTP post包头。
POST /webclient HTTP/1.1
Host: httpcm.example.com
Accept-Encoding: gzip, deflate
Content-Type: text/xml; charset=utf-8
Content-Length: 104
      from='[email protected]'
      hold='1'
      rid='1573741820'
      to='example.com'
      route='xmpp:example.com:9999'
      ver='1.6'
      wait='60'
      ack='1'
      xml:lang='en'
      xmlns=' http://jabber.org/protocol/httpbind'/>
但HTTP协议是无状态的协议。为了保证Server/Client连接,Server必须经常轮询Client的状态,为此0124中采用了BOSH(Bidirectional-streams Over Synchronous HTTP )技术保证在浏览器中也能传输XMPP数据。
在上图红色圆圈中,Server会将Client来的Post请求hold一段时间,直到有数据响应或者timeout才返回给Client。Client端如果收到数据响应,无论是否有数据需要传输,必须立即再发起一个Post请求。这样就有了一种心跳服务。因为只需要隔timeout时间轮询Client,大大减少了网络的数据传输量。
保护未加密连接
XMPP建议采用https来进行传输。但在只允许http传输的情况下,XMPP采用了SHA-1哈希算法来保证链路的安全性。
K(1) = hex(SHA-1(seed))
K(2) = hex(SHA-1(K(1)))
...
K(n) = hex(SHA-1(K(n-1)))
1. 首先在Client端生成两个随机数,seed和n。用seek和n可以计算出K(1)…K(n) n个数值。
2. Client在向Server传输数据时将newkey先设置成K(n)。
newkey='K(n)'
xmlns='http://jabber.org/protocol/httpbind'/>
3. Client在第二次传输时,将newkey设置成K(n-1)。
      sid='SomeSID'
      key=‘K(n-1)’
      xmlns=' http://jabber.org/protocol/httpbind'/>
4. Server端在收到第二个包的时候,根据公式K(n) = hex(SHA-1(K(n-1)))可以算出K1(n),与step 2中的K(n)比较就能够确定传输是可靠的。
为何传输顺序不是K1,K2,。。。Kn
假设Client先传key=’K(1)’,如果有监听Client/Server通信的话,监听者就能通过公式计算出K(2),那么传输就不可靠了。
Resource
http://shallon.javaeye.com/blog/126428