OpenFire Source Code 21: Openfie Optimization (below)

User business card

In the pre-initialization process, the user’s business card is posted. The same is not repeated here.

First modify the system properties first:

provider. vcard.className

org.jivesoftware.util.redis.expand.RedisVCardProvider

Then need to modify the VCardManager business card management class.

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 xmlReaders = new LinkedBlockingQueue(POOL_SIZE); public RedisVCardProvider() { super(); // Initialize the pool of sax readers for (int i=0; i

< p>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 VCardManager VCardEventDispatcher.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 events if (created) {// Alert listeners that a new vCard has been created VCardEventDispatcher.dispatchVCardCreated(username, vCardElement);} else if (updated) {// Alert listeners that a vCard has been updated VCardEventDispatcher.dispatchVCardUpdated(username, vCardElement);}} private Runnable createTaskByCreateVCard(final VCardProvider provider, final Strin g 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() {@Override public 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);} @Override public void initialize(XMPPServer server) {......} @Override public void start() {.. ....} @Override public void stop() {// Remove this module as a user event listener UserEventDispatcher.removeListener(eventHandler);} public void reset() {//vcardCache.clear();} @Override public Iterator  getFeatures() {ArrayList features = new ArrayList(); features.add("redis-vcard-temp"); return features.iterator();} private class EventHandler extends UserEventAdapter {@Overri de public 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(ona me); 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; }}

This is the end of the user card.

User search

When searching for users, the relational database is searched again in openfire. Because we have preloaded users into redis. So here only need to do some word segmentation storage and retrieval to the user.

I did a relatively simple word segmentation here. Such as user name, mobile phone number, etc.

The first thing to do is to make user segmentation. Then all you need to do is to modify the handler processing class of the search. A search plugin is provided on Openfire. The query message is finally submitted to the handler method of the SearchPlugin class. I will not describe it here. The key point is how to store words in redis.

The client sends a user search request as follows:

Please see the code list:

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() {......//Create connection pool} 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);} @Override public void initialize(XMPPServer server) {.....} //Create user search keyword data 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)");} //Here is divided according to the length of the string. Split according to "|" 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? u ser.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 write index

public class IndexWriter {private Jedis jedis; private String id; private Map items = new HashMap(); private String contentItems[]; public IndexWriter(Jedis jedis) {if (!jedis.isConnected()) {jedis. connect();} this.jedis = jedis;} /** * @param id * must have * @param content * is the content after segmentation by the word segmentation program, and each word must be separated by "|", such as: China|Chinese|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 > it = items.entrySet().iterator(); while (it.hasNext()) { Entry entry = (Entry) it.next(); jedis.set(entry.getKey().toString() + ":" + id, entry .getValue().toString( ));}} }}

IndexSearch: search index

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 isearch(int sort, String... query) {jedis.sinterstore("tempKey", query); return jedis.sort("tempKey", this.getSP(itemName, sort));} public List search(String... query) {return this.isearch(0, query);} public List search(int sort, String... query) {return this.isearch(sort, query);} public List search(String itemName, int sort, String... query) {this.itemName = itemName; return this.isearch(sort, query );} public List search(String itemName, int sort, int limit, String... query) {this.itemName = itemName; this.limit = limit; return this.isearch(sort, query);} public List 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 users search this and only post some more critical codes. Provide ideas. The code is posted too much and the length is very long.

Leave a Comment

Your email address will not be published.