用户名片

在预初始化中,贴出来用户名片的程序。这里也一样不在重复。

首先同样先修改系统属性:

provider.vcard.className

org.jivesoftware.util.redis.expand.RedisVCardProvider

然后需要修改VCardManager名片管理这个类。

RedisVCardProvider:

import redis.clients.jedis.Jedis;
public class RedisVCardProvider implements VCardProvider {private static final Logger Log = LoggerFactory.getLogger(RedisVCardProvider.class);private static final String DELETE_PROPERTIES ="DELETE FROM ofVCard WHERE username=?";private static final String UPDATE_PROPERTIES ="UPDATE ofVCard SET vcard=? WHERE username=?";private static final String INSERT_PROPERTY ="INSERT INTO ofVCard (username, vcard) VALUES (?, ?)";private static final int POOL_SIZE = 10;private BlockingQueue<SAXReader> xmlReaders = new LinkedBlockingQueue<SAXReader>(POOL_SIZE);public RedisVCardProvider() {super();// Initialize the pool of sax readersfor (int i=0; i<POOL_SIZE; i++) {SAXReader xmlReader = new SAXReader();xmlReader.setEncoding("UTF-8");xmlReaders.add(xmlReader);}}@Overridepublic Element loadVCard(String username) {synchronized (username.intern()) {Jedis jedis = XMPPServer.getInstance().getUserJedis().getJedis();Element vCardElement = null;SAXReader xmlReader = null;try {// Get a sax reader from the poolxmlReader = xmlReaders.take();String usercard = jedis.get("OFVCARD:" + username);if (usercard == null || "".equals(usercard)) {return XMPPServer.getInstance().getJedisConfDao().getVCardProvider().loadVCard(username);}vCardElement = xmlReader.read(new StringReader(usercard)).getRootElement();}catch (Exception e) {Log.error("Error loading vCard of username: " + username, e);}finally {if (xmlReader != null) {xmlReaders.add(xmlReader);}XMPPServer.getInstance().getUserJedis().returnRes(jedis);}return vCardElement;}}@Overridepublic Element createVCard(String username, Element vCardElement)throws AlreadyExistsException {......}@Overridepublic Element updateVCard(String username, Element vCardElement)throws NotFoundException {......}@Overridepublic void deleteVCard(String username) {......}@Overridepublic boolean isReadOnly() {// TODO Auto-generated method stubreturn false;}
}

VCardManager

/*** Manages VCard information for users.** @author Matt Tucker*/
public class VCardManager extends BasicModule implements ServerFeaturesProvider {private static final Logger Log = LoggerFactory.getLogger(VCardManager.class);private VCardProvider provider;private static VCardManager instance;private EventHandler eventHandler;private static HmThreadPool threadPool = new HmThreadPool(5);public static VCardManager getInstance() {return instance;}public static VCardProvider getProvider() {return instance.provider;}public VCardManager() {super("VCard Manager");//String cacheName = "VCard";//vcardCache = CacheFactory.createCache(cacheName);this.eventHandler = new EventHandler();// Keeps the cache updated in case the vCard action was not performed by VCardManagerVCardEventDispatcher.addListener(new VCardListener() {public void vCardCreated(String username, Element vCard) {// Since the vCard could be created by the provider, add it to the cache.//vcardCache.put(username, vCard);Jedis jedis = XMPPServer.getInstance().getUserJedis().getJedis();try {jedis.set("OFVCARD:" + username, vCard.asXML());} finally {XMPPServer.getInstance().getUserJedis().returnRes(jedis);}}public void vCardUpdated(String username, Element vCard) {// Since the vCard could be updated by the provider, update it to the cache.//vcardCache.put(username, vCard);vCardCreated(username, vCard);}public void vCardDeleted(String username, Element vCard) {// Since the vCard could be delated by the provider, remove it to the cache.//vcardCache.remove(username);Jedis jedis = XMPPServer.getInstance().getUserJedis().getJedis();try {jedis.del("OFVCARD:" + username);} finally {XMPPServer.getInstance().getUserJedis().returnRes(jedis);}}});}public String getVCardProperty(String username, String name) {......}public void setVCard(String username, Element vCardElement) throws Exception {boolean created = false;boolean updated = false;if (provider.isReadOnly()) {throw new UnsupportedOperationException("VCard provider is read-only.");}//Element newvCard = null;Jedis jedis = XMPPServer.getInstance().getUserJedis().getJedis();try {boolean exists = jedis.exists("OFVCARD:" + username);if (exists) {threadPool.execute(createTaskByUpdateVCard(provider, username, vCardElement));updated = true;}else {threadPool.execute(createTaskByCreateVCard(provider, username, vCardElement));created = true;}}finally {XMPPServer.getInstance().getUserJedis().returnRes(jedis);}// Dispatch vCard eventsif (created) { // Alert listeners that a new vCard has been createdVCardEventDispatcher.dispatchVCardCreated(username, vCardElement);} else if (updated) {// Alert listeners that a vCard has been updatedVCardEventDispatcher.dispatchVCardUpdated(username, vCardElement);}}private Runnable createTaskByCreateVCard(final VCardProvider provider, final String username, final Element vCardElement) {   return new Runnable() {   public void run() {try {provider.createVCard(username, vCardElement);} catch (AlreadyExistsException e) {Log.error("AlreadyExistsException: username=" + username + ", vCardElement=" + vCardElement);}}   };   } private Runnable createTaskByUpdateVCard(final VCardProvider provider, final String username, final Element vCardElement) {   return new Runnable() {   public void run() {try {provider.updateVCard(username, vCardElement);} catch (NotFoundException e) {Log.error("NotFoundException: username=" + username + ", vCardElement=" + vCardElement);}}   };   }public void deleteVCard(String username) {if (provider.isReadOnly()) {throw new UnsupportedOperationException("VCard provider is read-only.");}final String vusername = username;threadPool.execute(new Runnable() {@Overridepublic void run() {provider.deleteVCard(vusername);}});VCardEventDispatcher.dispatchVCardDeleted(username, null);}public Element getVCard(String username) {Element vCardElement = getOrLoadVCard(username);return vCardElement == null ? null : vCardElement.createCopy();}private Element getOrLoadVCard(String username) {return provider.loadVCard(username);}@Overridepublic void initialize(XMPPServer server) {......}@Overridepublic void start() {......}@Overridepublic void stop() {// Remove this module as a user event listenerUserEventDispatcher.removeListener(eventHandler);}public void reset() {//vcardCache.clear();}@Overridepublic Iterator<String> getFeatures() {ArrayList<String> features = new ArrayList<String>();features.add("redis-vcard-temp");return features.iterator();}private class EventHandler extends UserEventAdapter {@Overridepublic void userDeleting(User user, Map params) {try {deleteVCard(user.getUsername());} catch (UnsupportedOperationException ue) { /* Do Nothing */ }}}public UserCardEnity getUserCardByUserName (String username) {Element element = getVCard(username);UserCardEnity uce = new UserCardEnity();if (element != null) {String myName = element.elementText("MYNAME");String sex = element.elementText("SEX");String oname = element.elementText("ONAME");String moblie = element.elementText("MOBILE");String landline = element.elementText("LANDLINE");String address = element.elementText("ADDRESS");String workUnit = element.elementText("WORKUNIT");String birthday = element.elementText("BIRTHDAY");String photo = element.elementText("PHOTO");String userType = element.elementText("USERTYPE");uce.setMyName( myName);uce.setSex(sex);uce.setOname(oname);uce.setMoblie( moblie) ;uce.setLandline(landline);uce.setAddress(address);uce.setWorkUnit(workUnit) ;uce.setBirthday(birthday);uce.setPhoto(photo);if (userType == null) {uce.setUserType("");}else if (1 == Integer.valueOf(userType)) {uce.setUserType("student");}else if (2 == Integer.valueOf(userType)) {uce.setUserType("teacher");}else if (3 == Integer.valueOf(userType)) {uce.setUserType("Guardian");}else if (4 == Integer.valueOf(userType)) {uce.setUserType("edusun admin");}else if (5 == Integer.valueOf(userType)) {uce.setUserType("Agents");}else {uce.setUserType("Other locations");}}return uce;}
}

用户名片就到这了。

用户搜索

搜索用户的时候,在openfire中都是重新查找关系数据库的。因为我们已经将用户预加载到了redis中。那么这里只需要对用户做一些分词存储检索即可。

本人在这里做了比较简单的分词处理。比如用户名,手机号码等。

首先要做的就是制作用户分词了。然后要做的就是需要修修改搜索的handler处理类。Openfire上提供了一个search搜索插件。查询消息最后提交给SearchPlugin这个类的handler方法。本人这里就不做描述。重点要说的就是如何在redis中分词存储。

客户端发送用户查找请求如下:

<iq id="E6l1b-43" to="test@search.hytest240" type="get"><query xmlns="jabber:iq:search"></query></iq>

请看代码清单:

RedisSearchManager:

public class RedisSearchManager extends BasicModule{private static final Logger LOG = LoggerFactory.getLogger(RedisSearchManager.class);private static final Integer timeout = 1000*10;private static final int maxActive = 5000 * 10;private static final int maxIdle = 5;private static final long maxWait = (1000 * 100);private static JedisPool pool;private static XMPPServer loaclserver;private static JedisPoolConfig config;public RedisSearchManager() {super("Redis search manager");}private static JedisPoolConfig createConfig() {......}private static void createJedisPool() {......//创建连接池}private static synchronized void poolInit() {boolean enabled = JiveGlobals.getBooleanProperty("plugin.userservice.enabled");if (enabled) {if (pool == null)createJedisPool();}}public Jedis getSearchJedis() {if (pool == null)poolInit();Jedis jedis = pool.getResource();jedis.select(3);return jedis;}public void returnSearchJedis(Jedis jedis) {pool.returnResource(jedis);}@Overridepublic void initialize(XMPPServer server) {
.....}//创建用户的搜索关键词数据public void createSearchAllUserData() {Collection<User> userList = XMPPServer.getInstance().getUserJedis().getAllUser();for (User user : userList) {createSearchUserData(user);}System.out.println("Initialize the user search data is completed...(the end)");}//这里根据string长度切分。按照“|”分割public void createSearchUserData(User user) {Jedis jedis = getSearchJedis();IndexWriter iw = new IndexWriter(jedis);String username = user.getUsername();String keyword = "";if (username.length() >= 4) {int index = 4;for (int i=0; i<=username.length()-4; i++) {String usernameKey = username.substring(0, index++) + "|";keyword += usernameKey;}}else {keyword = username + "|";}if (user.getName() != null && !"".equals(user.getName())) {keyword += user.getName() + "|";}if (user.getEmail() != null && !"".equals(user.getEmail())) {keyword += user.getEmail() + "|";}if (user.getMoblie() != null && !"".equals(user.getMoblie())) {keyword += user.getMoblie();}if ("|".equals(keyword.substring(keyword.length()-1))) {keyword = keyword.substring(0, keyword.length()-1);}iw.addIdAndIndexItem(username, keyword);iw.addNeedSortItem("USERNAME",username);iw.addNeedSortItem("CREATIONDATE",user.getCreationDate() != null ? user.getCreationDate() : StringUtils.dateToMillis(new Date()));iw.addNeedSortItem("MODIFICATIONDATE",user.getModificationDate() != null ? user.getModificationDate() : StringUtils.dateToMillis(new Date()));iw.writer();System.out.println("create user search data, id:" + username + ", keyword:" + keyword);LOG.info("create user search data, id:" + username + ", keyword:" + keyword);returnSearchJedis(jedis);}
}

IndexWriter写入索引

public class IndexWriter {private Jedis jedis;private String id;private Map<String, String> items = new HashMap<String, String>();private String contentItems[];public IndexWriter(Jedis jedis) {if (!jedis.isConnected()) {jedis.connect();}this.jedis = jedis;}/*** @param id*            必须有* @param content*            是分词程序切分后的内容,每个词中间必须用用“|”分隔,如:中国|中国人|2012*/public void addIdAndIndexItem(String id, String content) {this.id = id;contentItems = content.split("\\|");}public void addNeedSortItem(String name, String value) {items.put(name, value);}public void writer() {indexWriter();itemWriter();}private void indexWriter() {if (!id.equals("") && contentItems.length != 0) {for (int i = 0; i < contentItems.length; i++) {jedis.sadd(contentItems[i].trim(), id);}}}private void itemWriter() {if (items.size() != 0) {Iterator<Entry<String, String>> it = items.entrySet().iterator();while (it.hasNext()) {Entry<String, String> entry = (Entry<String, String>) it.next();jedis.set(entry.getKey().toString() + ":" + id, entry.getValue().toString());}}}
}

IndexSearch:查找索引

public class IndexSearch {public static int ALPHA = 0;public static int DESC = 1;public static int ASC = 2;private Jedis jedis;private int limit = 100;private String itemName = null;private int pager = 0;public IndexSearch(Jedis jedis) {if (!jedis.isConnected()) {jedis.connect();}this.jedis = jedis;}private SortingParams getSP(String item, int sort) {SortingParams sp = new SortingParams();sp.limit(pager, limit);if (null == item || "".equals(item)) {switch (sort) {case 1:sp.desc();break;case 2:sp.asc();break;case 0:default:sp.alpha();break;}} else {switch (sort) {case 1:sp.by(itemName + ":*").desc();break;case 2:sp.by(itemName + ":*").asc();break;case 0:default:sp.by(itemName + ":*").alpha();break;}}return sp;}private List<String> isearch(int sort, String... query) {jedis.sinterstore("tempKey", query);return jedis.sort("tempKey", this.getSP(itemName, sort));}public List<String> search(String... query) {return this.isearch(0, query);}public List<String> search(int sort, String... query) {return this.isearch(sort, query);}public List<String> search(String itemName, int sort, String... query) {this.itemName = itemName;return this.isearch(sort, query);}public List<String> search(String itemName, int sort, int limit,String... query) {this.itemName = itemName;this.limit = limit;return this.isearch(sort, query);}public List<String> search(String itemName, int sort, int pager, int limit,String... query) {this.itemName = itemName;this.limit = limit;this.pager = pager;return this.isearch(sort, query);}
}

Ok用户搜索这就只贴出一些比较关键性的代码。提供思路。代码贴多了搞了篇幅很长。

OpenFire源码学习之二十二:openfie对用户的优化(下)相关推荐

  1. 【Qt】通过QtCreator源码学习Qt(十二):Q_D和Q_Q指针(简称“d指针”)详解

    1.Q_D和Q_Q指针(简称"d指针")简介 参考博客: https://www.devbean.net/2016/11/qt-creator-source-study-07/ h ...

  2. 手机自动化测试:appium源码分析之bootstrap十二

    手机自动化测试:appium源码分析之bootstrap十二 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请 ...

  3. 开源中国源码学习UI篇(二)之NavigationDrawer+Fragment的使用分析

    前文链接:开源中国源码学习UI篇(一)之FragmentTabHost的使用分析 开源中国2.2版,完整源码地址为:http://git.oschina.net/oschina/android-app ...

  4. OpenFire源码学习之二十九:openfire集群配置

    集群 Openfire的给集群提供了多种方案.一种是基于Hazelcast插件,还有基于Oracle的coherence插件. Oracle的coherence插件中文开发文档:http://down ...

  5. OpenFire源码学习之二十一:openfie对用户的优化(上)

    用户类 优化用户主要是要解决用户的连接量.已经对用户的访问速度和吞吐量. 预初始化 在前面的带面中提出来了用户的预初始化.这里就不在贴出来了.下面将redis用户库连接池处理贴出来UserJedisP ...

  6. OpenFire源码学习之十九:在openfire中使用redis插件(上)

    Redis插件 介绍 Redis是目前比较流行的NO-SQL,基于K,V的数据库系统.关于它的相关操作信息,本人这里就不做重复了,相关资料可以看这个网站http://www.redis.io/(官网) ...

  7. (转)OpenFire源码学习之十八:IOS离线推送

    转:http://blog.csdn.net/huwenfeng_2011/article/details/43458213 IOS离线推送 场景: 如果您有iOS端的APP,在会话聊天的时候,用户登 ...

  8. Android系统源码学习-SIM卡(二)

    随着手机的普及,大家从非智能机到智能机的转变,从没有操作系统的定制机到智能手机,但唯一没有变的是,手机中的SIM,今天我们就来谈谈手机中SIM卡相关的内容.在日常生活中,SIM卡就是一张很小的卡片,但 ...

  9. OpenFire源码学习之七:组与花名册

    Group 在openfire中的gorop--组,也可以理解为共享组.什么叫共享组呢.当有一个组名字为"学习组",当其他用户加入这个组的时候,那么他们会自动成为相互的好友.实际上 ...

  10. OpenFire源码学习之四:openfire的启动流程

    openfire启动 ServerStarter 启动流程图: 启动的总入口在ServerStarter的main方法中.通过上图首先它会先加载它所需要的jar文件.最后通过java反射机制将XMPP ...

最新文章

  1. 头条丨2017年人工智能现七大走向
  2. mysql导出数据 程序_MySQL数据导出与导入程序代码
  3. centos7下配置golang1.7.1环境(自己做测试了)
  4. 单机负载告警,数据库与应用分离
  5. 数据科学学习心得_学习数据科学
  6. ssh(struts,spring,hibernate)开发的初步集成01--依赖
  7. 重磅福利!《Apache Flink 十大技术难点实战》发布,帮你从容应对生产环境中的技术难题...
  8. Linux Shell脚本编程-语句控制
  9. Layout Management
  10. 基于Vue3+Go本地视频管理与播放系统设计与实现
  11. 如何用微信群、微信霸屏进行引流
  12. win10计算机如何调到桌面上,win10系统下怎么将计算器放在桌面上
  13. 2022电大国家开放大学网上形考任务-金融企业会计非免费(非答案)
  14. linux系统下深度学习环境搭建和使用
  15. UML图解简单工厂模式工厂方法模式抽象工厂模式区别
  16. Android内存优化之图片优化
  17. 用Python爬取豆瓣首页所有电影名称、每部电影影评及生成词云
  18. 华三模拟器完成交换机堆叠IRF实验
  19. 从“闪电战”到全面战:荣耀开启“吓人的技术”2.0时代
  20. 现代人工智能走在仿生学的大道上

热门文章

  1. 计算机应用笔试题及答案,计算机应用基础笔试试题及答案
  2. 八年级英语上册单词复习
  3. 好书分享:《写作提高一点点》
  4. 1999年世界卫生组织/国际高血压联盟关于高血压治疗指南
  5. 怎样把一个PSD文件里的图层移到另一个PSD文件里
  6. 为什么不可以后退?油门踩到底,回到最初的样子-学语言
  7. 游戏代理推广怎么选择平台?
  8. X86 X64 AMD64 IA64
  9. MyBatisPlus 中 基于 IService操作数据库的常用函数
  10. NXP iMX7 M4 核心 SPI Slave 测试