在XMPP的JAVA开源实现Openfire中,增加LBS 附近的人功能
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上同行的分享:
用经纬度做索引,
先粗算,比如把经纬度差一以上的全去掉,where latitude>y-1 and latitude<y+1 and longitude>x-1 and longitude <x+1 and ... ; x,y为当前用户的经纬度。
再小范围概算,使用类似这样的公式 order by abs(longitude -x)+abs(latitude -y) limit 100;
最后显示时再精确计算 使用类似这样的公式:(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>
以上两种思路的优缺点:
XEP 0080 : 官方扩展协议,比较通用,也更加符合LBS是一种特殊的message的理念; 但是可定制性不强,不能增加自己的很多业务逻辑,尤其是“附近的人”功能并不包含;
增加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
在XMPP的JAVA开源实现Openfire中,增加LBS 附近的人功能的更多相关文章
- Vim中增加ga键的vmap功能
ga是Vim自带的显示光标字符编码的功能,但是反过来,没有从编码显示对应字符的功能. 因为编码是多位数,所以可视模式下写了此功能. 规则: 纯数字认为是10进制 其他情况都认为是16进制 纯数字的话, ...
- PC-博客首页中增加必应或GOOGLE搜索功能
<script type="text/javascript" language="javascript"> function SearchGoogl ...
- java开源工具包-Jodd框架
java开源工具包-Jodd框架 / 2019-07-24 Jodd是一个Java工具包和微型框架,Jodd 工具包含一些实用的工具类和小型框架,增强了 JDK 提供很多强大的功能,可以帮助实现 ...
- 在附件管理模块中增加对FTP 上传和预览的支持
在之前介绍的附件管理模块里面<Winform开发框架之通用附件管理模块>以及<Winform开发框架之附件管理应用>,介绍了附件的管理功能,通过对数据库记录的处理和文件的管理, ...
- java开源即时通讯软件服务端openfire源码构建
java开源即时通讯软件服务端openfire源码构建 本文使用最新的openfire主干代码为例,讲解了如何搭建一个openfire开源开发环境,正在实现自己写java聊天软件: 编译环境搭建 调试 ...
- 解决openfire中发送某些特殊字符会断开xmpp连接的问题
在openfire中,如果发送某些特殊的字符(例如一些表情符合),会断开xmpp的连接,经查,是由以下的代码问题引起的: src\java\org\jivesoftware\openfire\net\ ...
- 开源一个Java Class实现Openfire登陆、推出、消息发送,方便其他系统集成IM功能了
开源一个Java Class实现Openfire登陆.推出.消息发送 N年前写的,希望对Openfire开发新手有帮助哦 import java.util.*; import java.io.*; ...
- (转)Openfire 中SASL的认证方式之:PLAIN,DIGEST-MD5,anonymous
转:http://blog.csdn.net/coding_me/article/details/39524137 SASL 的认证方式包括: 1. PLAIN:plain是最简单的机制,但 ...
- 11大Java开源中文分词器的使用方法和分词效果对比
本文的目标有两个: 1.学会使用11大Java开源中文分词器 2.对比分析11大Java开源中文分词器的分词效果 本文给出了11大Java开源中文分词的使用方法以及分词结果对比代码,至于效果哪个好,那 ...
随机推荐
- 2D image convolution
在学习cnn的过程中,对convolution的概念真的很是模糊,本来在学习图像处理的过程中,已对convolution有所了解,它与correlation是有不同的,因为convolution = ...
- mysql创建自定义函数与存储过程
mysql创建自定义函数与存储过程 一 创建自定义函数 在使用mysql的过程中,mysql自带的函数可能不能完成我们的业务需求,这时就需要自定义函数,例如笔者在开发过程中遇到下面这个问题 mysql ...
- bootstrap table 服务器端分页例子分享
这篇文章主要介绍了bootstrap table 服务器端分页例子分享,需要的朋友可以参考下 1,前台引入所需的js 可以从官网上下载 复制代码代码如下: function getTab(){var ...
- 3D触控简介:建立数字刻度应用及快速活动栏
苹果公司通过 iPhone 6s 和 6s Plus 引入了与手机互动的全新方式:按压手势.你也许知道,苹果智能手表和苹果笔记本电脑早已具备这一功能,只是名称略有不同,为力感触控(Force Touc ...
- [转贴]JAVA :RESTLET开发实例(一)基于JAX-RS的REST服务
RESTLET介绍 Restlet项目为“建立REST概念与Java类之间的映射”提供了一个轻量级而全面的框架.它可用于实现任何种类的REST式系统,而不仅仅是REST式Web服务. Restlet项 ...
- CKFinder 2.4 ASP.NET 破解
网上的破解教程对于2.4版本来说已经过时了. 以下是CKFinder 2.4 ASP.NET的亲测可用破解方法,经测试,只需修改两处代码. 打开ckfinder.js, 步骤1. 搜索替换如下代码: ...
- Beta Round #9 (酱油杯noi考后欢乐赛)最大伤害
题目:http://www.contesthunter.org/contest/Beta%20Round%20%EF%BC%839%20%28%E9%85%B1%E6%B2%B9%E6%9D%AFno ...
- 三招搞挂Mysql(转)
一.产生大量的undo日志 众所周知,InnoDB是一个支持MVCC的存储引擎,为了支持MVCC,InnoDB需要保存undo日志,以便对用户提供记录的历史版本.如果我们开启一个事务,反复地更新一条记 ...
- x64 stack walking、调用约定、函数参数识别
k = <rsp> <rip> <frame_count>x64下manual stack walking与x86不同,x86一般情况下有ebp chain,x64 ...
- 微软开放技术开发了适用于 Windows Azure 移动服务的开源 Android SDK
发布于 2014-02-10 作者 陈 忠岳 为进一步实现连接微软与非微软技术的目标,微软开放技术有限公司开发了适用于 Windows Azure 移动服务的 Android SDK,由Scot ...