我在通过smack库从ejabberd服务器18.01获取脱机消息时遇到问题。 我有一个连接器方法
private static AbstractXMPPConnection connectToServer(String serverHost, Integer port, String userName, String userPassword) {
DomainBareJid xmppDomain = null;
try {
xmppDomain = JidCreate.domainBareFrom(serverHost);
} catch (XmppStringprepException e) {
System.out.println("XMPP Domain initialization exception " + e.getMessage());
return null;
}
XMPPTCPConnectionConfiguration config = XMPPTCPConnectionConfiguration.builder()
.setXmppDomain(xmppDomain)
.setHost(serverHost)
.setPort(port)
.setDebuggerEnabled(true)
.setSendPresence(false)
.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled)
.build();
AbstractXMPPConnection connection = new XMPPTCPConnection(config);
try {
connection.connect().login(userName, userPassword);
return connection;
} catch (XMPPException | SmackException | IOException | InterruptedException e) {
System.out.println("Something went wrong while connection to server: " + e.getMessage());
connection.disconnect();
return null;
}
}
和离线消息接收器
private XMPPConnection connection;
@Override
public void run() {
connection = Connector.getInstance();
if (connection != null) {
System.out.println("Start listening messages in the background");
String offlineMessageOffline = "Offline message is %s from %s";
OfflineMessageManager offlineMessageManager = new OfflineMessageManager(connection);
try {
if (offlineMessageManager.supportsFlexibleRetrieval()) {
offlineMessageManager.getMessages()
.forEach(message -> {
System.out.println(String.format(offlineMessageOffline, message.getBody(), message.getFrom()));
});
// offlineMessageManager.deleteMessages();
}
} catch (SmackException.NoResponseException | XMPPException.XMPPErrorException |
SmackException.NotConnectedException | InterruptedException e) {
System.out.println(String.format("Error while getting offline messages from server: by the reason %s", e.getMessage()));
}
try {
connection.sendStanza(new Presence(Presence.Type.available));
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
ChatManager chatManager = ChatManager.getInstanceFor(connection);
IncomingChatMessageListener listener = (entityBareJid, message, chat) -> {
System.out.println(String.format("Incoming message is %s from %s", message.getBody(), message.getFrom()));
};
chatManager.addIncomingListener(listener);
} else {
System.out.println("Connection has not been established. Please try to choose option 1");
}
}
我开始在后台运行消息监听器。我看到该数据库有一个离线消息,在dubug节点中,我看到offlineMessageManager.getMessageCount()返回正确数量的离线消息,但方法offlineMessageManager.getMessages()返回注释。 smack版本是4.2.3但早期版本有同样的问题
更新
我找到了一种解决方法,因为它看起来不是一个明显的解决方案
public class ListenMessagesFromServerCommand implements Runnable {
private XMPPConnection connection;
@Override
public void run() {
connection = Connector.getInstance();
if (connection != null) {
System.out.println("Start listening messages in the background");
String offlineMessageOffline = "Offline message is %s from %s";
OfflineMessageManager offlineMessageManager = new OfflineMessageManager(connection);
try {
if (offlineMessageManager.supportsFlexibleRetrieval() && offlineMessageManager.getMessageCount() > 0) {
List<String> messagesNodes = offlineMessageManager.getHeaders().stream()
.map(OfflineMessageHeader::getStamp)
.collect(Collectors.toList());
offlineMessageManager.getMessages(messagesNodes)
.forEach(message -> {
System.out.println(String.format(offlineMessageOffline, message.getBody(), message.getFrom()));
});
offlineMessageManager.deleteMessages();
}
} catch (SmackException.NoResponseException | XMPPException.XMPPErrorException |
SmackException.NotConnectedException | InterruptedException e) {
System.out.println(String.format("Error while getting offline messages from server: by the reason %s", e.getMessage()));
}
try {
connection.sendStanza(new Presence(Presence.Type.available));
} catch (SmackException.NotConnectedException | InterruptedException e) {
System.out.println("Error sending presence available type " + e.getMessage());
}
ChatManager chatManager = ChatManager.getInstanceFor(connection);
IncomingChatMessageListener listener = (entityBareJid, message, chat) -> {
System.out.println(String.format("Incoming message is %s from %s", message.getBody(), message.getFrom()));
};
chatManager.addIncomingListener(listener);
} else {
System.out.println("Connection has not been established. Please try to choose option 1");
}
}
}