[英]Unable to receive Message using Smack (Java)?
我正在尝试建立一个简单的示例,以使用Openfire使用Smack API发送和接收消息。 我已经按照本教程
有人在这里问过同样的问题,但是答案提到了我已经用于接收聊天的代码。 这些示例中的许多示例也使用相同的方法。
public class Receiver {
public static void main(String a[]) throws XMPPException, InterruptedException {
XMPPConnection connection = new XMPPConnection("192.168.1.38");
System.out.println(connection);
connection.connect();
connection.login("test2", "123456");
EFLogger.LogInfo("Receiver", "Connected [ " + connection.isConnected() + " ]");
connection.getChatManager().addChatListener(new ChatManagerListener() {
public void chatCreated(Chat chat, boolean b) {
System.out.println("In Message Listener ! ");
chat.addMessageListener(new MessageListener() {
public void processMessage(Chat chat, Message message) {
System.out.println("Message [ " + message.toXML());
}
});
try {
chat.sendMessage("Hello");
} catch (XMPPException e) {
e.printStackTrace();
}
}
});
while (true) {
}
}
}
为了发送,我正在使用
public class Main {
public static void main(String[] args) throws Exception {
String username = "test";
String password = "123456";
XmppManager xmppManager = new XmppManager("192.168.1.38", 5222);
xmppManager.init();
xmppManager.performLogin(username, password);
xmppManager.setStatus(true, "Hello everyone");
//As @MrPk suggested I shouldn't use "/Smack"
//String buddyJID = "test2@ef-app2/Smack";
String buddyJID = "test2@ef-app2";
String buddyName = "test";
xmppManager.createEntry(buddyJID, buddyName);
for (int i = 0; i < 10; i++) {
xmppManager.sendMessage("Hello mate from test " + i, "test2");
}
boolean isRunning = true;
while (isRunning) {
Thread.sleep(50);
}
xmppManager.destroy();
}
}
此类是XMPPManager
/**
This class is responsible for handling all Actions related to Chat Management. Connection, Login, Status, Create Entry and Message Listener.
*/
public class XmppManager {
private static final int packetReplyTimeout = 500; // millis
private String server;
private int port;
private ConnectionConfiguration config;
private XMPPConnection connection;
private ChatManager chatManager;
private MessageListener messageListener;
public XmppManager(String server, int port) {
this.server = server;
this.port = port;
}
public void init() throws XMPPException {
EFLogger.LogInfo("XmppManager", String.format("Initializing connection to server %1$s port %2$d", server, port));
SmackConfiguration.setPacketReplyTimeout(packetReplyTimeout);
// SmackConfiguration.DEBUG = true;
config = new ConnectionConfiguration(server, port);
config.isDebuggerEnabled();
connection = new XMPPConnection(config);
connection.connect();
EFLogger.LogInfo("XmppManager", "Connected: " + connection.isConnected());
chatManager = connection.getChatManager();
//messageListener = new MyMessageListener();
}
public void performLogin(String username, String password) throws XMPPException {
if (connection != null && connection.isConnected()) {
EFLogger.LogInfo("XmppManager", "Before login userName [ " + username + " ] password [ " + password + " ]");
connection.login(username, password);
System.out.printf("Logged in ");
}
}
public void setStatus(boolean available, String status) {
Presence.Type type = available ? Type.available : Type.unavailable;
Presence presence = new Presence(type);
presence.setStatus(status);
connection.sendPacket(presence);
}
public void destroy() {
if (connection != null && connection.isConnected()) {
connection.disconnect();
}
}
public void sendMessage(String message, String buddyJID) throws XMPPException {
EFLogger.LogInfo("XmppManager", String.format("Sending mesage '%1$s' to user %2$s", message, buddyJID));
Chat chat = chatManager.createChat(buddyJID, messageListener);
chat.sendMessage(message);
}
public void createEntry(String user, String name) throws Exception {
EFLogger.LogInfo("XmppManager", String.format("Creating entry for buddy '%1$s' with name %2$s", user, name));
Roster roster = connection.getRoster();
roster.createEntry(user, name, null);
}
static class MyMessageListener implements MessageListener {
public void processMessage(Chat chat, Message message) {
String from = message.getFrom();
String body = message.getBody();
EFLogger.LogInfo("XmppManager", String.format("Received message '%1$s' from %2$s", message.getError(), from));
}
}
}
首先,我认为buddyID一定有问题,我有这两个用户test
和test2
而XMPPdomain是ef-app2
所以我将buddyJID test2@ef-app2/Smack
smack设置为默认资源。
建议@MrPk不应该使用/ Smack ,但是不要碰运气。
但仍然没有影响,我仍然无法收到任何消息。 我不确定我缺少什么。 如果您有兴趣重现同样的问题,你可以找到IntelliJ IDEA的项目在这里你可以得到有关该问题的一些细节在这里
救命!
启动聊天应用程序时,我使用了相同的教程。 它或多或少是一个很好的教程,但实际上是极简主义:让我们逐点检查主要改进和错误修复。
在开始之前,您将需要2个用户:您可以从test2@ef-app2
消息发送给自己(您只能使用Broadcast进行广播,但这太高级了)。 只需在服务器上注册第二个用户即可。
因此,您将需要test1@ef-app2
(与之聊天)和test2@ef-app2
(在您的应用中登录)。
首先,建议您在计算机上安装Spark客户端。 因此,您将能够拥有一个“肯定能正常工作”的客户端,并且您将能够在Spark和Java应用程序之间实时进行聊天,当然需要使用2个用户。 我喜欢Spark,因为它具有出色的调试器,可让您检查发送和接收的Stanzas,因此基本上,当您不知道自己是否正确时,只需检查Spark的功能即可。
SmackConfiguration.setPacketReplyTimeout(3000); //default
不要减少默认超时。 我从50000开始,现在有7000(表示7秒)。
在此之前或之后,您需要改进连接的配置,或多或少像这样:
protected XMPPTCPConnectionConfiguration config;
protected AbstractXMPPConnection connection;
this.config = XMPPTCPConnectionConfiguration.builder()
.setServiceName(serviceName) //Often is NOT the IP address of Host
.setHost(server)
.setPort(port)
.setSecurityMode(SecurityMode.disabled) //if you don't need
.setDebuggerEnabled(true) //really helpfull
.build();
this.connection = new XMPPTCPConnection(config);
this.connection.connect();
在不提供用户,密码和资源的情况下连接服务器。
注意: config.isDebuggerEnabled();
这是一个获取,而不是集合(因此,您不启用它,而只是che之以鼻...)
要登录,我建议像这样设置一个自定义 Resource标识符 (有些东西没有使用或默认设置就会损坏 )->避免使用“ Smack”和“ Spark”进行更好的调试。 使用类似“ MyApp”的名称。
connection.login(username, password, "MyApp");
基本思想是:每当您在“我”和“另一个人”之间开始聊天时,客户端应用程序都必须为“另一个人”的传入消息添加一个侦听器。 因此,您必须向ChatManager添加一个用于管理单个聊天侦听器的侦听器。 我将向您展示“基本所有匿名”版本,如果愿意,您可以拆分为单个定义的类。
//add to ChatManager a listener to manage incoming "person"
ChatManager.getInstanceFor(connection).addChatListener(
new ChatManagerListener() {
@Override
public void chatCreated(Chat chat, boolean createdLocally)
{
//if it's the first message in session between 2 users
if (!createdLocally)
{
//add a listeners for those message just once
chat.addMessageListener(new ChatMessageListener()
{
@Override
public void processMessage( Chat arg0, Message arg1 )
{
//example to read something in standard output
String from = message.getFrom();
String body = message.getBody();
if (body != null)
{
System.out.println(String.format("============ Received message '%1$s' from %2$s\n============", body, from));
}
else
{
System.out.println("SYSTEM: ping (body null)");
}
}
};
}
}
});
基本上,您必须再等待一点时间才能销毁客户端。 如果您之前使用独立的客户端(例如Spark I)将用户“ test2”连接到服务器“ ef-app2”,则将轻松检查是否收到任何消息。 主要外观如下:
xmppManager.performLogin("test2@ef-app2", "123456". "MyApp");
xmppManager.createEntry("test1@ef-app2", "My friend"); //test1 ONE!
xmppManager.sendMessage("Hello world", "test1@ef-app2");
boolean isRunning = true;
while (isRunning) {
Thread.sleep(50000);
i++;
if (i > 2)
{
//xmppManager.performLogout();
isRunning = false;
xmppManager.destroy();
}
}
检入调试发生了什么以及发送和接收的最终XML是什么。 您将可以与Spark one进行比较。 如果默认消息不起作用,请尝试以下代码:
Message message = new Message();
message.setBody(body);
message.setType(Message.Type.chat);
message.setTo("test2@ef-app2");
message.setFrom("test1@ef-app2");
try {
connection.sendStanza(message);
} catch (NotConnectedException e) {
System.out.println("Not connected!");
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.