Openfire本身是支持离线消息的,不需要进行额外地对Openfire数据库中ofoffline操作,smack已经提供好接口,但是,如果直接用smack中的OfflineMessageManager直接获取,是获取不到的,离线消息数量总是为零。
由于Openfire规定,处理离线信息的时候,在连接之前,就要先将状态要设为离线。也就是说,在用户登录部分,你要补上config.setSendPresence(false);的代码,例如,如下是我Openfire的一段登录方法,你要对离线信息进行处理,必须补上这样的一行代码:
// 用户登录
public String login() throws XMPPException {
if (checkPassword(username, password)) {
msg = "登录成功!";
ConnectionConfiguration config = new ConnectionConfiguration(
"127.0.0.1", 5222, "serverName");
Connection connection = new XMPPConnection(config);
config.setSendPresence(false);//必须先将用户的登录状态设置为离线才能拿到离线消息
connection.connect();
connection.login(username, password);
Map session = ActionContext.getContext().getSession();
session.put("username", username);
session.put("connection", connection);
return SUCCESS;
} else {
msg = "密码错误!";
return INPUT;
}
}
如图所示:
之后,才能用OfflineMessageManager获取离线信息,然后获取完再通知服务器删除离线信息,同时将用户设置为上线:
// 离线信息的获取
private void get_offline_message() throws XMPPException {
Connection connection = (Connection) session.get("connection");
OfflineMessageManager offlineManager = new OfflineMessageManager(
connection);//用OfflineMessageManager获取离线信息
System.out.println("离线消息数量: " + offlineManager.getMessageCount());
Iterator<Message> it = offlineManager.getMessages();
while (it.hasNext()) {
Message message = it.next();
System.out.println("收到离线消息:" + "Received from 【"
+ message.getFrom() + "】 message: " + message.getBody());
}
offlineManager.deleteMessages();//通知服务器删除离线信息
Presence presence = new Presence(Presence.Type.available);//将用户设置为上线
connection.sendPacket(presence);
}
上述代码运行结果大致如下:
注意自行引入:
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smackx.OfflineMessageManager;
不知道为什么Openfire这样设计的,默认是上线状态,直接删除所有离线信息,也就是直接将ofoffline的东西全删掉,OfflineMessageManager再也获取不到。
但是,如果你通过上述Presence切成上线状态,Openfire则不会自动删除ofoffline的内容,必须通过offlineManager.deleteMessages();才能删除。