XMPP是什么,第1张

1, xmpp是最早由jabber提出的一整套即时通讯协议,开发即时通讯软件用。

2, 不是

3,阅读协议,开发出符合协议的程序即可

4,Jabber服务器有Openfire等

提出问题:这种功能必须涉及client(客户端)和server(服务器),所以到底client如何和server实现实时连接通讯?

分析问题:这种功能实际上就是数据同步,同时要考虑手机本身、电量、网络流量等等限制因素,所以通常在移动端上有一下两个解决方案:

1一种是定时去server查询数据,通常是使用HTTP协议来访问web服务器,称Polling(轮询);

2还有一种是移动端和服务器建立长连接,使用XMPP长连接,称Push(推送)。(按照本人理解:客户端的实现时:

while(true) {

 request(timeout);

 request(timeout);

}

客户端发出一个“长”请求,如果服务器发送消息或者时间out了,客户端就断开这个请求,再建立一个长请求

从耗费的电量、流量和数据延迟性各方面来说,Push有明显的优势。但是使用Push的缺点是:

对于客户端:实现和维护相对成本高,在移动无线网络下维护长连接,相对有一些技术上的开发难度。

对于服务器:如何实现多核并发,cpu作业调度,数量庞大的长连接并发维护等技术,仍存在开发难点。

在讲述Push方案的原理前,我们先了解一下移动无线网络的特点。

移动无线网络的特点:

因为 IP v4 的 IP 量有限,运营商分配给手机终端的 IP 是运营商内网的 IP,手机要连接 Internet,就需要通过运营商的网关做一个网络地址转换(Network Address Translation,NAT)。简单的说运营商的网关需要维护一个外网 IP、端口到内网 IP、端口的对应关系,以确保内网的手机可以跟 Internet 的服务器通讯

 

原理图如下:

 

                                         

        

GGSN(Gateway GPRS Support Node 网关GPRS支持结点)模块就实现了NAT功能。

因为大部分移动无线网络运营商都是为了减少网关的NAT映射表的负荷,所以如果发现链路中有一段时间没有数据通讯时,会删除其对应表,造成链路中断。(关于NAT的作用及其原理可以查看我的另一篇博文:关于使用UDP(TCP)跨局域网,NAT穿透的心得)

 

Push在Android平台上长连接的实现:

既然我们知道我们移动端要和Internet进行通信,必须通过运营商的网关,所以,为了不让NAT映射表失效,我们需要定时向Internet发送数据,因为只是为了不然NAT映射表失效,所以只需发送长度为0的数据即可。

这时候就要用到定时器,在android系统上,定时器通常有一下两种:

1javautilTimer

2androidappAlarmManager

分析:

Timer:可以按照计划或者时间周期来执行相关的任务。但是Timer需要用WakeLock来让CPU保持唤醒状态,才能保证任务的执行,这样子会消耗大量流量;当CPU处于休眠的时候,就不能唤醒执行任务,所以应用于移动端明显是不合适。

AlarmManager:AlarmManager类是属于android系统封装好来管理RTC模块的管理类。这里就涉及到RTC模块,要更好地了解两者的区别,就要明白两者真正的区别。

RTC(Real- Time Clock)实时闹钟在一个嵌入式系统中,通常采用RTC 来提供可靠的系统时间,包括时分秒和年月日等;而且要求在系统处于关机状态下它也能够正常工作(通常采用后备电池供电),它的外围也不需要太多的辅助电路,典型的就是只需要一个高精度的32768KHz 晶体和电阻电容等。(如果对这方面感兴趣,可以自己查阅相关资料,这里就说个大概)

好了,回来正题。所以,AlarmManager又称全局定时闹钟。这意味着,当我用使用AlarmManager来定时执行任务,CPU可以正常地休眠,只有在执行任务是,才唤醒CPU,这个过程是很短时间的。

下面简单来说明其使用:

1类似于Timer功能:

//获得闹钟管理器

AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);

//设置任务执行计划

amsetRepeating(AlarmManagerELAPSED_REALTIME, firstTime, 51000, sender);//从firstTime才开始执行,每隔5秒再执行

2实现全局定时功能:

//获得闹钟管理器

AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);

//设置任务执行计划

amsetRepeating(AlarmManagerELAPSED_REALTIME_WAKEUP, firstTime, 51000, sender);//从firstTime才开始执行,每隔5秒再执行

总结:在android客户端使用Push推送时,应该使用AlarmManager来实现心跳功能,使其真正实现长连接。

在服务器端的实现:

在服务器端,可以使用很多语言来实现,如C/C++,java,Erlang等等,如我们国内比较好的极光推送(C开发),openfire(java开发)等等。

最近我看了极光推送的介绍和原理,下面我就说说他们是遇到什么难题,然后使用什么技术或者方案来解决呢。

当有大量的手机终端需要与服务器维持长连接时,对服务器的设计会是一个很大的挑战。

假设一台服务器维护10万个长连接,当有1000万用户量时,需要有多达100台的服务器来维护这些用户的长连接,这里还不算用于做备份的服务器,这将会是一个巨大的成本问题。那就需要我们尽可能提高单台服务器接入用户的量,也就是业界已经讨论很久了的 C10K 问题。

C2000K

针对这个问题,他们专门成立了一个项目,命名为C2000K,顾名思义,他们的目标是单机维持200万个长连接。最终他们采用了多消息循环、异步非阻塞的模型,在一台双核、24G内存的服务器上,实现峰值维持超过300万个长连接。

最后总结:

        因为我最近用java在做一个PC、服务器、android的即时通讯系统(说白了就是模仿QQ,后面希望有不同的功能)。我的原则是用别人的原理,自己来实现,这样才更好深入了解一些框架。所以,估计难点是在通讯开发和服务器上的开发,必须深刻了解多消息循环、异步非阻塞的模型。之后我会发表关于这方面的实现。

       在现在的android平台上,已经不是android单机的世界了(我不是说做单机游戏没有前途)。现在都是依靠发展蓬勃的互联网来支撑整个IT体系,所以,要成为一个android应用开发高手,必须朝着android、硬件、云服务这一体系来发展。

基于即时通信的社交app。我们选择的是xmpp协议,服务端的选择是tiagse。原本我们最初的选择是openfire,但是由于openfire相比较于tigase做集群的难度大,后来就选择了tigase。好了废话不多说。搭建一个在windows平台下的tigase服务器。

第一步:

到tigase的官网下载tigase的jar包。我选的版本是tigase-server-520-b3447jar。下载地址是https://projectstigaseorg/projects/tigase-server/files

第二步:

安装tigase服务器。双击下载之后的tigase jar包,前提是配置了java的环境变量。

第三步:

选择java环境变量所在路径

第四步:

选择tigase安装路径

第五步

选择配置

第六步:

配置数据

第七步:

一直点击next直到结束,找到安装路径,运行tigase。

到这里tigase就安装完成了。

测试tigase是否可以使用,安装一个spark,就能测试了。

socket是套接字,在你的语境下,多指传输层网络接口。

webSocket,是一个应用层协议,说的是,目前浏览器实现的一套通信协议,用来解决之前HTTP,请求响应模型不合适的场合。

XMPP,是一个应用层协议,协议基于XML结构设计。

其实websocket是socket的简约实现,与socket相比,可以节省额外的端口占用,直接使用一个公网域名访问。另外协议对报文的流量消耗做了优化。xmpp与websocket比也是比较臃肿的

xmpp是im的使用比较广泛的协议,早期的手机端推送为了省事就用的这种协议,但是后来发现这种协议比较臃肿耗流量,而且对服务器要求比较高

我认为不是 两个peer要会话就需要把各自的sdp发送到对方,如果两者都在局域网(nat)之后,怎么发送?这时候就需要一个在公网上的能直接访问的中间者来传递消息,在这之前两者都是tcp连接在中间服务器上的。这个中间服务器除了转发sdp,还会传递candidate,它包含stun之后的信息,有了这个peer之间就能直接传media数据了。peer通过ice组件向stun服务器协商后获得了candidate,所以这个信令服务器并不是ICE server,用google 文档上的话说,这个信令服务器可以是普通的socketserver,也可以sip/xmpp/Websocket服务器

QQ微信这些都用的自己的协议,而且不会公开。

对于小一点的公司想要实现实时聊天,一开始从XMPP做起是不错的选择。因为它是一个公开的标准,又有很多开源的实现,比如你提到的Openfire, aSmack和XMPPFramework,可以花费较少的开发量,就可以搭建出一套还算好用的实时聊天方案。

起步之后,你会想要添加更多的功能,XMPP有很多扩展,很多需求都能满足。一般来说,要做的产品都是服务器、客户端都由自己掌控,不需要和其他的厂商的聊天服务器/客户端互联互通,所以之后可以慢慢在XMPP上加入自己的扩展,甚至是一些删改(因为XMPP里面不少机制是为了适应不同公司的组件)。于是渐渐的,最后使用的协议可能已经和标准的XMPP不一样了,成了自己的协议。

这样从XMPP上演进出来的协议,虽然具体实现和XMPP可能相差不少,但是基本思想和原理又与XMPP一致。相比自己从头设计出一套全新的协议,基于这样一套经过无数项目考验过的协议,显然容易得多,风险也要小得多。

刚开始研究XEP-0045,感觉它应该能实现群的基本功能。

某个xmpp账号加入某个多人聊天(房间),如果房间不存在,服务器会临时创建,则此账号的岗位(affiliation)自动被为owner,便可以对房间进行配置(可以用pidgin感受一下,创建room后消息框里输入"/config"),比如设置群为永久群,设置主题(类似群名称)、设置为只允许成员加入、设置成员不能改变主题等,还可以添加删除成员(pidgin消息框中输入"/affiliate member abc@localhost",abc@localhost登录后加入此房间,便可发言、接收发言、查询成员列表等)

<img src="https://pic4zhimgcom/90be25b77f184e762d1af4b7ede9b717_bjpg" data-rawwidth="1222" data-rawheight="1424" class="origin_image zh-lightbox-thumb" width="1222" data-original="https://pic4zhimgcom/90be25b77f184e762d1af4b7ede9b717_rjpg">

这些功能理论上都应该能用程序实现,只是难易的问题,就看所用的xmpp客户端库对XEP-0045实现的如何。

我这里服务器使用的ejabberd,账号登录是通过外部服务认证,账号状态、消息都要通过外部服务记录(要写扩展,利用ejabberd的钩子和事件,现成的相关插件有ejabberd_auth_http、mod_http_offline、mod_muc_log_http、mod_post_log),ejabberd本身只是起到一个消息枢纽的作用,所以离线消息的存储,我不打算通过ejabberd本身实现,外部服务保存消息时若发现账号离线,可通过推送通知到客户端,客户端启动后可直接从外部服务获取。

我也刚才入门不久,不一定理解得全对,提供一些线索供参考。另外,我也在考虑mqtt是不是能满足需求。

DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
网站模板库 » XMPP是什么

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情