conference spark默认的是临时的,就是用户点击后才能加入到群组里面,关闭后从群组里退出。
要修改spark的这个功能,提供以下思路(原创)
一、 spark用户在登陆的时候 ,在openfire 进行SessionEventListener,通过插件的形式进行监听,在sessionCreated的时候进行,登陆用户的joinRoom ,从数据库取出他所在的groupname 然后进行joinroom。
作法; 在openfire写一个插件,插件主要代码如下:
private JID serverAddress;
private JoinGroupsSessionEventListener listener = new JoinGroupsSessionEventListener();
private XMPPServer server;
private MultiUserChatServiceImpl mucService;
private class JoinGroupsSessionEventListener implements SessionEventListener {
public void sessionCreated(Session session) {
System.out.println("a client connect!");
JID userJid=session.getAddress();
JoinGroups(userJid);
}public void sessionDestroyed(Session session) {
//ignore
JID userJid=session.getAddress();
LeaveGroups(userJid);
}public void resourceBound(Session session) {
// Do nothing.
}public void anonymousSessionCreated(Session session) {
//ignore
}public void anonymousSessionDestroyed(Session session) {
//ignore
}
}
@Override
public void initializePlugin(PluginManager manager, File pluginDirectory) {
// TODO Auto-generated method stub
server=XMPPServer.getInstance();
//mucService=server.getMultiUserChatManager().getMultiUserChatService(ser)
serverAddress = new JID(XMPPServer.getInstance().getServerInfo().getXMPPDomain());
SessionEventDispatcher.addListener(listener);
System.out.println("join groups plugin is running!");
}public void LeaveGroups(JID userJid) {
System.out.println(userJid.toBareJID()+" is leaving the room!");
List<String> roomIds=MUCPersistenceManager.getRoomIDsByUserJid(userJid.toBareJID());
for(String roomId:roomIds)
{
System.out.println("room id:"+roomId);
org.jivesoftware.openfire.muc.spi.RoomInfo rminf=MUCPersistenceManager.getRoomInfoByRoomId(roomId);
String serviceID=rminf.getServiceID();
mucService=(MultiUserChatServiceImpl)server.getMultiUserChatManager().getMultiUserChatService(Long.parseLong(rminf.getServiceID()));
System.out.println("service id:"+serviceID);
String roomName=rminf.getName();
System.out.println("room name:"+roomName);
LocalMUCRoom room=(LocalMUCRoom)mucService.getChatRoom(roomName);
//从数据库中查询他的姓名作为昵称(得自己实现)
String nickname = MUCPersistenceManager.getNickNameByJId(userJid.toBareJID());
if(nickname == null)
{
if(userJid.getNode() != null)
{
nickname = userJid.getNode();
}
else
{
nickname = userJid.getResource();
}
}
// The user leaves the room 用户离开群
try {
if(!room.hasOccupant(nickname))
return;
LocalMUCRole role=(LocalMUCRole) room.getOccupant(nickname);
room.leaveRoom(role);
System.out.println("leaved!");
} catch (UserNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}public void JoinGroups(JID userJid) {
System.out.println(userJid.toBareJID()+" is joining the room!");
try{
List<String> roomIds=MUCPersistenceManager.getRoomIDsByUserJid(userJid.toBareJID());
for(String roomId:roomIds)
{
System.out.println("room id:"+roomId);
org.jivesoftware.openfire.muc.spi.RoomInfo rminf=MUCPersistenceManager.getRoomInfoByRoomId(roomId);
String serviceID=rminf.getServiceID();
mucService=(MultiUserChatServiceImpl)server.getMultiUserChatManager().getMultiUserChatService(Long.parseLong(rminf.getServiceID()));
System.out.println("service id:"+serviceID);
String roomName=rminf.getName();
System.out.println("room name:"+roomName);
LocalMUCRoom room=(LocalMUCRoom)mucService.getChatRoom(roomName);
//从数据库中查询他的姓名作为昵称(得自己实现)
String nickname = MUCPersistenceManager.getNickNameByJId(userJid.toBareJID());
if(nickname == null)
{
if(userJid.getNode() != null)
{
nickname = userJid.getNode();
}
else
{
nickname = userJid.getResource();
}
}
HistoryRequest historyRequest = null;
String password = null;
//构建成员进入群的Presence
Presence presence = new Presence();
presence.setTo(room.getJID().toBareJID() + "/" + nickname);
presence.setFrom(userJid);
PacketExtension extension = new PacketExtension("x", "http://jabber.org/protocol/muc");
presence.addExtension(extension);
PacketRouter pr=server.getPacketRouter();
LocalMUCUser user=new LocalMUCUser(mucService, pr, userJid);
// The user joins the room 用户进入群
try {
LocalMUCRole role = room.joinRoom(nickname,
password,
historyRequest,
user,
presence);
System.out.println("joined!");
user.addRole(roomName, role);
} catch (UnauthorizedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UserAlreadyExistsException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (RoomLockedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ForbiddenException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (RegistrationRequiredException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ConflictException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ServiceUnavailableException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NotAcceptableException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}catch(Exception e)
{
e.printStackTrace();
}
}@Override
public void destroyPlugin() {
// TODO Auto-generated method stub
SessionEventDispatcher.removeListener(listener);
listener = null;
serverAddress = null;
server=null;
mucService=null;
}
在 MUCPersistenceManager 这个类里 添加如下方法 ,用于上面的使用
// 石坚 20120609
public static List<String> getRoomIDsByUserJid(String userJid) {
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
List<String> roomIDs=new ArrayList<String>();
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(LOAD_ROOMIDS_BY_JID);
pstmt.setString(1, userJid);
rs = pstmt.executeQuery();
while(rs.next()) {
String roomId = rs.getString("roomID");
roomIDs.add(roomId);
}
}
catch (SQLException sqle) {
Log.error(sqle.getMessage(), sqle);
}
finally {
DbConnectionManager.closeConnection(rs, pstmt, con);
}
return roomIDs;
}
public static String getRoomNameByRoomId(String roomId) {
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
String roomName=null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(LOAD_ROOMNAME_BY_ROOMID);
pstmt.setString(1, roomId);
rs = pstmt.executeQuery();
if(rs.next()) {
roomName= rs.getString("name");
}
}
catch (SQLException sqle) {
Log.error(sqle.getMessage(), sqle);
}
finally {
DbConnectionManager.closeConnection(rs, pstmt, con);
}
return roomName;
}
public static String getServiceIdByRoomId(String roomId) {
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
String serviceID=null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(LOAD_SERVICEID_BY_ROOMID);
pstmt.setString(1, roomId);
rs = pstmt.executeQuery();
if(rs.next()) {
serviceID= rs.getString("serviceID");
}
}
catch (SQLException sqle) {
Log.error(sqle.getMessage(), sqle);
}
finally {
DbConnectionManager.closeConnection(rs, pstmt, con);
}
return serviceID;
}
public static String getNickNameByJId(String userJid) {
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
String nick=null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(LOAD_NICKNAME_BY_JID);
pstmt.setString(1, userJid);
rs = pstmt.executeQuery();
if(rs.next()) {
nick= rs.getString("nickname");
}
}
catch (SQLException sqle) {
Log.error(sqle.getMessage(), sqle);
}
finally {
DbConnectionManager.closeConnection(rs, pstmt, con);
}
return nick;
}
public static RoomInfo getRoomInfoByRoomId(String roomId) {
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
RoomInfo rminf=null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(LOAD_ROOMINFO_BY_ROOMID);
pstmt.setString(1, roomId);
rs = pstmt.executeQuery();
if(rs.next()) {
String serviceID= rs.getString("serviceID");
String name= rs.getString("name");
String naturalName= rs.getString("naturalName");
String description=rs.getString("description");
rminf=new RoomInfo(serviceID, name, naturalName, description);
}
}
catch (SQLException sqle) {
Log.error(sqle.getMessage(), sqle);
}
finally {
DbConnectionManager.closeConnection(rs, pstmt, con);
}
return rminf;
}
public static List<String> getMembersByRoomId(String roomId) {
// TODO Auto-generated method stub
List<String> members=new ArrayList<String>();
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(LOAD_JIDS_BY_ROOMID);
pstmt.setString(1, roomId);
rs = pstmt.executeQuery();
while(rs.next()) {
String jid= rs.getString("jid");
members.add(jid);
}
}
catch (SQLException sqle) {
Log.error(sqle.getMessage(), sqle);
}
finally {
DbConnectionManager.closeConnection(rs, pstmt, con);
}
return members;
}
// end
二、用户登陆了群,在进行打开chatroom的时候,spark默认的是显示的在线的用户,要进行修改 。增加一个可以发送离线用户列表的方法:
private void sendOfflineUserList(LocalMUCRole joinRole){
// TODO Auto-generated method stub
String roomId=""+getID();
List<String> members=MUCPersistenceManager.getMembersByRoomId(roomId);
System.out.println("member count:"+members.size());
for(String jid:members)
{
JID userJid=new JID(jid);
System.out.println("jid:"+userJid.toBareJID());
MUCRole role=getOccupantByFullJID(userJid);
if(null==role) {
// TODO Auto-generated catch block
try{
System.out.println("member not found!");
String nickname = MUCPersistenceManager.getNickNameByJId(userJid.toBareJID());
if(nickname == null)
{
if(userJid.getNode() != null)
{
nickname = userJid.getNode();
}
else
{
nickname = userJid.getResource();
}
}
//构建presence
Presence presence = new Presence();
String sjid=getJID().toBareJID() + "/" + nickname;
presence.setTo(sjid);
presence.setFrom(sjid);
PacketExtension extension = new PacketExtension("x", "http://jabber.org/protocol/muc#user");
presence.addExtension(extension);
Element frag=presence.getChildElement("x","http://jabber.org/protocol/muc#user");
Element item=frag.addElement("item");
item.addAttribute("jid",userJid.toBareJID()+"/"+(userJid.getResource()==null?nickname:userJid.getResource()));
//item.addAttribute("affilication",userJid.toFullJID());
System.out.println("occupantPresence :n"+presence.toXML()+"nn");
joinRole.send(presence);//发送presence
}catch(Exception e)
{
e.printStackTrace();
}
}
}
}
此方法要添加在Localmucroom 的sendinitialpresences 方法的末尾就可以。
//发送离线成员列表给新成员
sendOfflineUserList(joinRole);
第三步: 离线用户发送到了 客户端 但是显示是有问题,所以 进行排序,让在线的在前面
修改org.jivesoftware.spark.ui.conferences; 的 GroupChatParticipantList类。修改如下
public int compare(JLabel item1, JLabel item2) {
int result=compareByPresence(item1.getIcon().toString(), item2.getIcon().toString());
if(0==result)
{
if (_localPreferences.isShowingRoleIcons()) {
return compareWithRole(item1, item2);
} else {
return compareWithoutRole(item1.getText(), item2.getText());
}
}
return result;
}
//通过在线状态比较两个列表项
//在线<离线 若状态相同则按默认排序规则进行排序 返回 0 ,1 ,-1
private int compareByPresence(String s1, String s2) {
Icon iconAvaliable=SparkRes.getImageIcon(SparkRes.GREEN_BALL);
String iconStr=iconAvaliable.toString();
return s1.equals(s2)?0:s1.equals(iconStr)?-1:1;
}
private int compareWithoutRole(String s1, String s2) {
return (s1.toLowerCase().compareTo(s2.toLowerCase()));
}
/**
* Comparaes 2 items by their Role and Affiliation<br>
* affiliation > role<br>
* owner > admin > moderator > member > participant > visitor
* @param item1
* @param item2
* @return -1, 0 or 1
*/
private int compareWithRole(JLabel item1, JLabel item2) {
int user1 = 100;
int user2 = 100;
try {
// append Room-JID to UserLabel
String jid1 = chat.getRoom() + "/" + item1.getText();
String jid2 = chat.getRoom() + "/" + item2.getText();
user1 = getCompareValue(jid1);
user2 = getCompareValue(jid2);
} catch (Exception e) {
// Sometimes theres no Occupant with that jid, dunno why
}
int result = 0;
if (user1 == user2) {
result = compareWithoutRole(item1.getText(), item2.getText());
} else {
// a=owner,b=admin, m=moderator, n=member , p=participant, v=visitor
// a < b < m < n < p < v
if (user1 < user2)
result = -1;
if (user1 > user2)
result = 1;
}
return result;
}