I am trying to setup a simple example for sending and receiving messages with Smack API using Openfire. I have followed this tutorial
Someone asked the same question about the situation here , but the answer mentions the code which I am already using for receiving the chat. Many of these examples using the same method as well.
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) {
}
}
}
For sending, I am using
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();
}
}
and this class is 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));
}
}
}
First I thought there must be a problem with buddyID, I have these two users test
and test2
and XMPPdomain is ef-app2
so I set the buddyJID test2@ef-app2/Smack
smack is default resource.
@MrPk suggested shouldn't use /Smack , but no luck.
but still, it has no impact I am still unable to receive any message. I am not sure what I am missing. If you are interested in reproducing the same issue, you can find the IntelliJ IDEA project here you can get some more details about the issue here
Help!
When I started my chat application I used the same tutorial. It's more or less a good tutorial but really minimalist: let's check point by point major improvements and errors to fix.
Before start, you'll need 2 users: you'll can send from test2@ef-app2
messages to itself (you'll can do only with Broadcast, but it's too adavanced topic). Just register also the second user on your server.
So you'll need test1@ef-app2
(to chat with) and test2@ef-app2
(login in your app).
First of all, I suggest you to install Spark client on your machine. So you'll be able to have a client that "works for sure" and you'll be able to chat with yourself between Spark and your java application in real time, of course using 2 users. I liked Spark because it has a great debugger that allows you to check Stanzas sended and received, so basically when you don't know if you are right, just check what Spark does.
SmackConfiguration.setPacketReplyTimeout(3000); //default
Don't reduce default timeout. I started with 50000, now I have a 7000 (that means 7 seconds).
Before or later you'll need to improve Configuration of connection, more or less like this:
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();
To connect to server without provide user, password and Resource.
Pay attention: config.isDebuggerEnabled();
it's a get, not a set (so you are not enabling it but just cheking...)
To login, I suggest to set a custom Resource idenitifier (there is something that brokes without or with default one) like this -> avoid "Smack" and "Spark" to debug better. Use something like "MyApp".
connection.login(username, password, "MyApp");
Basic idea is: everytime you start a chat between "me" and "another person", client app has to add a listener for incoming messages of "another person". So you have to add a Listener to ChatManager that manages... single chat listeners. I'll show you "basic all anonymous" version, you'll can split in single defined classes if you'll like.
//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)");
}
}
};
}
}
});
Basically you'll have to wait a little more before destroy the client. If you'll have user "test2" connected to server "ef-app2" with a standalone client like Spark I mentonied before, you'll check easly if you received any message. Main will looks like:
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();
}
}
Check in both debug what happenned and what is the final XML sended and received. You'll can compare with Spark one. If default message will not works, try this code:
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!");
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.