文档章节

在XMPP的JAVA开源实现Openfire中,增加LBS 附近的人功能

杨子江
 杨子江
发布于 2013/12/20 22:12
字数 1079
阅读 5.9K
收藏 8

「深度学习福利」大神带你进阶工程师,立即查看>>>


1. XMPP协议 与 Openfire

XMPP协议是IM领域的标准协议了,具体可参考  http://xmpp.org   及RFC6120,RFC6121,RFC6122等相关文档。 http://xmpp.org/xmpp-protocols/   

XMPP协议实现,开源的也很多,server端可参考 http://xmpp.org/xmpp-software/servers/    client可以参考 http://xmpp.org/xmpp-software/clients/    library等可参考 http://xmpp.org/xmpp-software/libraries/    

其中XMPP协议的JAVA实现 Openfire 热门程度很高,也许取决于其安装使用门槛低以及底层基于MINA框架的经典实现等优势。

http://igniterealtime.org/projects/openfire 


2. LBS之附近的人 

在移动设备上,几乎大多数的IM类应用都有“附近的人”功能,其原理也非常简单,每一个用户若要查看自己附近的其他用户,则须上传自己的地理位置(GPS,基站定位)以共享;

server端则通过计算地球上两点距离来推送一定半径内的其他用户信息给使用者。


具体算法实现,我们参考大家通用的做法,比如来自zhihu上同行的分享:

用经纬度做索引,

  1. 先粗算,比如把经纬度差一以上的全去掉,where latitude>y-1 and latitude<y+1 and longitude>x-1 and longitude <x+1 and ... ; x,y为当前用户的经纬度。

  2. 再小范围概算,使用类似这样的公式 order by abs(longitude -x)+abs(latitude -y) limit 100;

  3. 最后显示时再精确计算 使用类似这样的公式:(2 * 6378.137* ASIN(SQRT(POW(SIN(PI()*(y-lat)/360),2)+COS(PI()*x/180)* COS(lat * PI()/180)*POW(SIN(PI()*(x-lng)/360),2))))。

前两项在数据库端计算,后一项在应用服务器端计算即可。

3. XMPP协议扩展

如果要在XMPP协议上增加LBS功能,那么需要我们扩展XMPP,增加新的请求和响应报文。

目前有两种思路来扩展 XMPP,一种是官方的扩展,见XEP0080   http://xmpp.org/extensions/xep-0080.html ,就是在message中增加LBS信息;

Example 1. Entity publishes location

<iq type='set' from='portia@merchantofvenice.lit/pda' id='publish1'>
 
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
   
<publish node='http://jabber.org/protocol/geoloc'>
     
<item>
       
<geoloc xmlns='http://jabber.org/protocol/geoloc' xml:lang='en'>
         
<accuracy>20</accuracy>
         
<country>Italy</country>
         
<lat>45.44</lat>
         
<locality>Venice</locality>
         
<lon>12.33</lon>
       
</geoloc>
     
</item>
   
</publish>
 
</pubsub>
</iq>
   

Example 2. Subscriber receives event with payload

<message from='portia@merchantofvenice.lit' 
         
to='bassanio@merchantofvenice.lit'>
 
<event xmlns='http://jabber.org/protocol/pubsub#event'>
   
<items node='http://jabber.org/protocol/geoloc'>
     
<item id='d81a52b8-0f9c-11dc-9bc8-001143d5d5db'>
       
<geoloc xmlns='http://jabber.org/protocol/geoloc' xml:lang='en'>
         
<accuracy>20</accuracy>
         
<country>Italy</country>
         
<lat>45.44</lat>
         
<locality>Venice</locality>
         
<lon>12.33</lon>
       
</geoloc>
     
</item>
   
</items>
 
</event>
</message>
   


另一种思路是通过添加自定义的IQ指令来实现,比如我们设计如下:

REQUEST

<iq id="c919" type="get" from="chris@im.nodexy.com/TCL-S960">
<query xmlns="com.nodexy.im.openfire.location">
    <item user="chris" lon="22.323009" lat="29.098763"/>
</query>

注意:

默认iq不设置to属性,则表示发送给 openfire server ,即to=im.nodexy.com ;

如果user a希望将自己的地理位置信息共享发送给好友user b,则需要显式设置to=userb@domain  ;此时server只会转发此IQ消息不会做其他处理。


RESPONSE

<iq id="c919" type="result" from="chris@im.nodexy.com/TCL-S960">
<query xmlns="com.nodexy.im.openfire.location">
    <item user="chris1" lon="22.323009" lat="29.098763" sex="0" online="30min"/>
    <item user="chris2" lon="22.323009" lat="29.098763" sex="0" online="30min"/>
    <item user="chris3" lon="22.323009" lat="29.098763" sex="0" online="30min"/>
    ... ...
</query>


以上两种思路的优缺点:

  1. XEP 0080 : 官方扩展协议,比较通用,也更加符合LBS是一种特殊的message的理念; 但是可定制性不强,不能增加自己的很多业务逻辑,尤其是“附近的人”功能并不包含;

  2. 增加IQ指令: 更加灵活,按需使用,支持“附近的人”甚至“附近的商家”等;当然缺点就是不通用,属于私有协议,以私有插件形式实现。


本文我们主要采用第二种。


4. Openfire插件实现 

在Openfire中实现LBS功能,可以采用开发新插件的方式来实现上面的扩展协议。

关于openfire插件开发可参考  http://www.igniterealtime.org/builds/openfire/docs/latest/documentation/plugin-dev-guide.html 


5. 代码分享

笔者这里分享一个基础版本的OpenfireLBS插件   https://github.com/node/openfireLBS  



杨子江

杨子江

粉丝 62
博文 3
码字总数 1646
作品 0
深圳
架构师
私信 提问
加载中
此博客有 5 条评论,请先登录后再查看。
Netty那点事(三)Channel与Pipeline

Channel是理解和使用Netty的核心。Channel的涉及内容较多,这里我使用由浅入深的介绍方法。在这篇文章中,我们主要介绍Channel部分中Pipeline实现机制。为了避免枯燥,借用一下《盗梦空间》的...

黄亿华
2013/11/24
2W
22
访问安全控制解决方案

本文是《轻量级 Java Web 框架架构设计》的系列博文。 今天想和大家简单的分享一下,在 Smart 中是如何做到访问安全控制的。也就是说,当没有登录或 Session 过期时所做的操作,会自动退回到...

黄勇
2013/11/03
3.5K
6
用vertx实现高吞吐量的站点计数器

工具:vertx,redis,mongodb,log4j 源代码地址:https://github.com/jianglibo/visitrank 先看架构图: 如果你不熟悉vertx,请先google一下。我这里将vertx当作一个容器,上面所有的圆圈要...

jianglibo
2014/04/03
4.2K
3
浅入浅出Android(003):使用TextView类构造文本控件

基础: TextView是无法供编辑的。 当我们新建一个项目MyTextView时候,默认的布局(/res/layout/activity_main.xml)中已经有了一个TextView: <TextView 运行效果如下: 修改其文本内容...

樂天
2014/03/22
670
1
SQLServer实现split分割字符串到列

网上已有人实现sqlserver的split函数可将字符串分割成行,但是我们习惯了split返回数组或者列表,因此这里对其做一些改动,最终实现也许不尽如意,但是也能解决一些问题。 先贴上某大牛写的s...

cwalet
2014/05/21
9.6K
0

没有更多内容

加载失败,请刷新页面

加载更多

如何在Git历史记录中grep(搜索)已提交的代码 - How to grep (search) committed code in the Git history

问题: I have deleted a file or some code in a file sometime in the past. 我过去某个时候已经删除了文件或文件中的某些代码。 Can I grep in the content (not in the commit messages)......

技术盛宴
29分钟前
9
0
二进制安装安装mysql 8.0.20

MySQL最新版本8.0.20正式发布。与之前8.0的系列版本一样,这次的发行版除了包含缺陷修复,也同样包括新功能。下面快速浏览一下。关键字:hash join、InnoDB双写缓冲、二进制日志事务压缩。 ...

程序员面试吧
33分钟前
18
0
关于python3.8+ pyside2 pyinstaller打包的一些坑

环境: python 3.8 pyinstaller 3.6 pyside2 5.14 打包过程中出现错误(1):   7607 WARNING: lib not found: pywintypes38.dll dependency of c:\users\have_\appdata\local\programs\pyth......

齐勇cn
33分钟前
11
0
备战秋招!静电的UI设计教室全能课程开始招生~系统进阶!提升核心竞争力

。 本文分享自微信公众号 - 静Design(JingDesign91)。 如有侵权,请联系 support@oschina.cn 删除。 本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。...

静电1983
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部