离线用户与离线消息
接下来就基于Chat-Portlet的源码做一些改动,实现一些小的功能,也算是对Liferay学习暂时告一段落。原先的Chat-Portlet只能查看在线用户,那如果想给离线的用户留言怎么办?增加功能:获取全部的好友列表(包括离线用户)。
1. 离线消息存储在数据库中。在查询数据库时,返回的是全部的用户。查询数据库的函数在findByModifiedDate@StatusFinderImpl。在查找数据库时,取消Chat_Status.online=1的限制,即要求用户的状态不必是在线状态,并将Chat_Status.online的值返回。
public List<Object[]> findByModifiedDate(long companyId, long userId,long modifiedDate, int start, int end) throws SystemException {
Session session = null;
try {
session = openSession();
String sql = CustomSQLUtil.get(FIND_BY_MODIFIED_DATE);
sql = " SELECT User_.userId AS userId, User_.screenName AS screenName, User_.firstName AS firstName, User_.middleName AS middleName, User_.lastName AS lastName, User_.portraitId AS portraitId, Chat_Status.awake AS awake,Chat_Status.online_ AS online FROM Chat_Status INNER JOIN User_ ON (User_.userId = Chat_Status.userId) WHERE (User_.companyId = ?) AND (User_.userId != ?) AND (Chat_Status.modifiedDate > ?) ORDER BY Chat_Status.awake ASC, User_.firstName ASC, User_.middleName ASC, User_.lastName ASC";
SQLQuery q = session.createSQLQuery(sql);
q.addScalar("userId", Type.LONG);
q.addScalar("screenName", Type.STRING);
q.addScalar("firstName", Type.STRING);
q.addScalar("middleName", Type.STRING);
q.addScalar("lastName", Type.STRING);
q.addScalar("portraitId", Type.LONG);
q.addScalar("awake", Type.BOOLEAN);
//返回状态标志
q.addScalar("online", Type.BOOLEAN);
QueryPos qPos = QueryPos.getInstance(q);
qPos.add(companyId);
qPos.add(userId);
qPos.add(modifiedDate);
return (List<Object[]>) QueryUtil.list(q, getDialect(), start, end);
} catch (Exception e) {
throw new SystemException(e);
} finally {
closeSession(session);
}
}
2.因为用户登录时,在Openfire服务器上也同时登录了,所以要根据Openfire上登录用户的Presence来判断其状态,返回的用户列表按顺序(是否唤醒、名字字典顺序)排序,其中在线的用户在前,离线的用户在后,处理排序的函数在getStatuses@JabberImpl中。
public List<Object[]> getStatuses(long companyId, long userId, List<Object[]> buddies) {
try {
Connection connection = getConnection(userId);
if (connection == null) {
if (_log.isWarnEnabled()) {
_log.warn("User " + userId + " is not connected to Jabber");
}
return buddies;
}
List<Object[]> jabberBuddies = new ArrayList<Object[]>();
//jabberBuddies.addAll(buddies);
Roster roster = connection.getRoster();
Collection<RosterEntry> rosterEntries = roster.getEntries();
if (PortletPropsValues.JABBER_IMPORT_USER_ENABLED) {
for (Object[] buddy : buddies) {
String screenName = (String)buddy[1];
String firstName = (String)buddy[2];
String middleName = (String)buddy[3];
String lastName = (String)buddy[4];
String fullName = ContactConstants.getFullName(firstName, middleName, lastName);
String jabberId = getFullJabberId(screenName);
if (!roster.contains(jabberId)) {
roster.createEntry(jabberId, fullName, null);
}
}
}
List<Object[]> jabberOffline = new ArrayList<Object[]>();
BuddyComparator buddyComparator = new BuddyComparator(true);
for (RosterEntry rosterEntry : rosterEntries) {
Presence presence = roster.getPresence(rosterEntry.getUser());
User user = UserLocalServiceUtil.getUserByScreenName(companyId, getScreenName(rosterEntry.getUser()));
Object[] jabberBuddy = new Object[8];
jabberBuddy[0] = user.getUserId();
jabberBuddy[1] = user.getScreenName();
jabberBuddy[2] = user.getFirstName();
jabberBuddy[3] = user.getMiddleName();
jabberBuddy[4] = user.getLastName();
jabberBuddy[5] = user.getPortraitId();
jabberBuddy[6] = true;
jabberBuddy[7] = true;
if (!presence.isAvailable()) {
jabberBuddy[6] = false;
jabberBuddy[7] = false;
jabberOffline.add(jabberBuddy);
continue;
}
if (Collections.binarySearch(jabberBuddies, jabberBuddy, buddyComparator) < 0) {
jabberBuddies.add(jabberBuddy);
}
}
Collections.sort(jabberBuddies, buddyComparator);
Collections.sort(jabberOffline,buddyComparator);
for(int i = 0;i < jabberOffline.size();i++)
{
jabberBuddies.add(jabberOffline.get(i));
}
return jabberBuddies;
}
catch (Exception e) {
_log.error("Unable to get Jabber buddies", e);
return buddies;
}
}
3.返回的数据格式是JSON格式的,需要增加新的<key,value>对,key为online,value为是否在线的Boolean值,处理的函数在getBuddies@ChatPollerProcessor。
4. main.js处理页面前端的显示,回调函数_onPollerUpdate中调用_updateBuddies更新好友列表。收到应答后,对于返回的用户列表的每个用户,判断其online属性,如果是在线用户,则在用户名右端添加“[在线]”字样,否则,在用户名右端添加“[离线]”字样。
for (var i = 0; i < numBuddies; i++) {
var buddy = buddyList[i];
if(buddy.online==true){
instance._onlineBuddiesCount = instance._onlineBuddiesCount+1;
}
var currentBuddy = currentBuddies[buddy.userId];
var currentChat = currentChats[buddy.userId];
buddy.isTyping = false;
if (currentChat && (!currentBuddy || currentBuddy.statusMessage != buddy.statusMessage)) {
currentChat.updateStatus(buddy.statusMessage);
}
currentBuddies[buddy.userId] = buddy;
var userImagePath = Liferay.Chat.Util.getUserImagePath(buddy.portraitId);
var stat;
if(buddy.online==true)
{
stat = buddy.fullName + " [在线]";
buffer.push('<li class="user active" userId="' + buddy.userId + '">' +
'<img alt="" src="' + userImagePath + '" />' +
'<div class="name">' + stat + '</div>' +
'<div class="buddy-services">');
}
else
{
stat = buddy.fullName + " [离线]";
buffer.push('<li class="user active" userId="' + buddy.userId + '">' +
'<img style ="filter:Alpha(opacity=10,finishOpacity=0,style=0);" alt="" src="' + userImagePath + '" />' +
'<div class="name">' + stat + '</div>' +
'<div class="buddy-services">');
}
var serviceNames = instance._buddyServices;
for (var serviceName in serviceNames) {
buffer.push('<div class="' + serviceName + '"></div>');
}
buffer.push('</div>' +'</li>');
}
只是接触Liferay的一点点皮毛,所以如果有说的不对的地方,欢迎批评指正。:)