使用 openfire media proxy

 

htt://blog.csdn.net/laorer

 

用 xmpp协议完成p2p语音聊天的软件,通过jingle ice协议实现p2p(把本地的IP/Port和NAT转换后的IP/Port<如果需要的话>发送给对方),但当这两种方式行不通的时候,就需要用到 Relay服务器了,即通过服务器转发,使用Openfire 服务器的话,可以开启 Media Proxy 服务。


客户端发送rtpbridge请求(这一块是自定义的协议,所以如果不是用 smack的话,需要自己去实现rtpbridge)(参考1)

<iq type='get' id='cand1' to='rtpbridge.serverdomain'> <rtpbridge xmlns='http://www.jivesoftware.com/protocol/rtpbridge' sid='session1'> <candidate/> </rtpbridge > </iq> 服务端将会返回 <iq type='result' id='cand1'> <rtpbridge xmlns='http://www.jivesoftware.com/protocol/rtpbridge' sid='session1'> <candidate name='myvoicedata' ip='200.10.11.104' porta='13540' portb='12555' pass='pxpxpx'/> </rtpbridge > </iq>   

这时可以把 ip/portb发送给对方,然后本地监听ip/porta,并把语音数据发往这个地址(rtcp端口在porta/portb上加1即可),这样就可以实现通过 media proxy通过了。有点需要注意的是,ip返回的可能是域名,所以需要通过域名获得ip地址。

使用中碰到的问题,portb返回为 0,这是服务端引起的,需要改下类(参考2)org.jivesoftware.openfire.mediaproxy.MediaProxySession
第88行开始改为下面的内容

 

this.socketA = new DatagramSocket(localPortA); //, this.localAddress); this.socketAControl = new DatagramSocket(localPortA + 1); //, this.localAddress); this.localPortB = getFreePort(); this.socketB = new DatagramSocket(localPortB); //, this.localAddress); this.socketBControl = new DatagramSocket(localPortB + 1); //, this.localAddress); 另外,如果 media proxy返回正常(porta,portb不为0)但还不能连通看下端口(10000-20000)防火墙是不是被挡了,我试着把范围调下,但似乎不成功……

1.Using Media Proxy with Jingle
http://www.igniterealtime.org/community/message/173118#173118

2.MediaProxy throwing exceptions (when openfire is running on Windows)
http://www.igniterealtime.org/community/message/146623#146623

你可能感兴趣的:(session,服务器,防火墙,smack,p2p,XMPP)