Xmpp Smack Chat not able to send and receiving message - xmpp

I have tried to establish chat connection between two users using xmpp and OpenFire. But i am not able to send and receive message. I have pasted my code below for reference. Any help will be very helpful.
I established a connection with Smack by
XMPPTCPConnectionConfiguration.Builder config = XMPPTCPConnectionConfiguration.builder();
config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
config.setUsernameAndPassword("admin", "admin");
config.setServiceName("172.21.4.199");
config.setHost("172.21.4.199");
config.setPort(5222);
config.setDebuggerEnabled(true);
config.setConnectTimeout(50000);
XMPPTCPConnection connection = new XMPPTCPConnection(config.build());
XMPPTCPConnection.setUseStreamManagementResumptiodDefault(true);
XMPPTCPConnection.setUseStreamManagementDefault(true);
try {
connection.setPacketReplyTimeout(50000);
connection.connect();
Log.d(TAG, "SetupDefaults -- Connected");
} catch (Exception e) {
e.printStackTrace();
Log.d(TAG, "SetupDefaults -- Connection failed exc: "+e);
}
and its gets succesfully connected. And i try to send a chat by using
ChatManager chatManager = ChatManager.getInstanceFor(connection);
Chat chat = chatManager.createChat("user2#server.local", new ChatMessageListener() {
#Override
public void processMessage(Chat chat, Message message) {
System.out.println("processMessage -- Sent message: " + message);
}
});
try {
chat.sendMessage("Hai.. Lets we chat!");
}catch (Exception e){
Log.d(TAG, "sendChat Exc: "+e.toString());
}
But i couldn't find that processMessage gets triggered. Because that S.O.P doesn't gets triggered. But i gets
SMACK: SENT (0): Hai.. Lets we chat!
SMACK: RECV (0): Hai.. Lets we chat!
in my console while sending a chat.
Simillarly i use,
PacketListener packetListener = new PacketListener() {
#Override
public void processPacket(Stanza packet) throws SmackException.NotConnectedException {
Message message = (Message)packet;
String from = message.getFrom();
String body = message.getBody();
System.out.println("Message from: " + from + " " + body);
}
};
connection.addPacketListener(packetListener, filter);
to receive the chat. But processPacket also doesn't gets triggered.

PacketListner it's something much more general to handle stanzas, it's not what you really need. You just need a ChatMessageListner
ChatManager chatManager;
chatManager = ChatManager.getInstanceFor(connection);
chatManager.addChatListener(
**new ChatManagerListener() {
#Override
public void chatCreated(Chat chat, boolean createdLocally)
{
if (!createdLocally)
{
chat.addMessageListener(new IncomingMessageListener());;
}
}
})**;
Basic implementation:
class IncomingMessageListener implements ChatMessageListener {
#Override
public void processMessage(Chat arg0, Message message) {
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));
guiUpdate.displayMessage(body); /* custom method */
}
else
{
System.out.println("SYSTEM: ping");
}
}

Related

Netty connection pool not sending messages to server

I have a simple netty connection pool and a simple HTTP endpoint to use that pool to send TCP messages to ServerSocket. The relevant code looks like this, the client (NettyConnectionPoolClientApplication) is:
#SpringBootApplication
#RestController
public class NettyConnectionPoolClientApplication {
private SimpleChannelPool simpleChannelPool;
public static void main(String[] args) {
SpringApplication.run(NettyConnectionPoolClientApplication.class, args);
}
#PostConstruct
public void setup() throws Exception {
EventLoopGroup group = new NioEventLoopGroup();
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group);
bootstrap.channel(NioSocketChannel.class);
bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
bootstrap.remoteAddress(new InetSocketAddress("localhost", 9000));
bootstrap.handler(new ChannelInitializer<SocketChannel>() {
protected void initChannel(SocketChannel socketChannel) throws Exception {
ChannelPipeline pipeline = socketChannel.pipeline();
pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
pipeline.addLast(new StringDecoder());
pipeline.addLast(new StringEncoder());
pipeline.addLast(new DummyClientHandler());
}
});
simpleChannelPool = new SimpleChannelPool(bootstrap, new DummyChannelPoolHandler());
}
#RequestMapping("/test/{msg}")
public void test(#PathVariable String msg) throws Exception {
Future<Channel> future = simpleChannelPool.acquire();
future.addListener((FutureListener<Channel>) f -> {
if (f.isSuccess()) {
System.out.println("Connected");
Channel ch = f.getNow();
ch.writeAndFlush(msg + System.lineSeparator());
// Release back to pool
simpleChannelPool.release(ch);
} else {
System.out.println("not successful");
}
});
}
}
and the Server (ServerSocketRunner)
public class ServerSocketRunner {
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(9000);
while (true) {
Socket socket = serverSocket.accept();
new Thread(() -> {
System.out.println("New client connected");
try (PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));) {
String inputLine, outputLine;
out.println("Hello client!");
do {
inputLine = in.readLine();
System.out.println("Received: " + inputLine);
} while (!"bye".equals(inputLine));
System.out.println("Closing connection...");
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
}
}
DummyChannelPoolHandler and DummyClientHandler just print out events that happen, so they are not relevant. When the server and the client are started and I send a test message to test endpoint, I can see the server prints "New client connected" but the message sent by client is not printed. None of the consecutive messages sent by client are printed by the server.
If I try telnet, everything works fine, the server prints out messages. Also it works fine with regular netty client with same bootstrap config and without connection pool (SimpleNettyClientApplication).
Can anyone see what is wrong with my connection pool, I'm out of ideas
Netty versioin: 4.1.39.Final
All the code is available here.
UPDATE
Following Norman Maurer advice. I added
ChannelFuture channelFuture = ch
.writeAndFlush(msg + System.lineSeparator());
channelFuture.addListener(writeFuture -> {
System.out
.println("isSuccess(): " + channelFuture.isSuccess() + " : " + channelFuture.cause());
});
This prints out
isSuccess: false : java.lang.UnsupportedOperationException: unsupported message type: String (expected: ByteBuf, FileRegion)
To fix it, I just converted String into ByteBuf
ch.writeAndFlush(Unpooled.wrappedBuffer((msg + System.lineSeparator()).getBytes()));
You should check what the status of the ChannelFuture is that is returned by writeAndFlush(...). I suspect it is failed.

Vertx: Timeout in message reply

I have a sender and a consumer that exchange messages:
public class Sender extends AbstractVerticle {
#Override
public void start() {
EventBus eventBus = vertx.eventBus();
eventBus.send(Constants.ADDRESS, "Hello from sender", res -> {
if (res.succeeded()) {
System.out.println("Successfully sent reply");
} else {
System.out.println("Failed to send reply." + res.cause());
}
});
eventBus.consumer(Constants.ADDRESS, msg -> System.out.println("received msg from consumer:" + msg.body()));
}
public class Consumer extends AbstractVerticle{
protected EventBus eventBus = null;
#Override
public void start() {
eventBus = vertx.eventBus();
eventBus.consumer(Constants.ADDRESS, msg -> msg.reply("Hi from consumer.", res -> {
if (res.succeeded()) {
System.out.println("Successfully sent reply");
} else {
System.out.println("Failed to send reply." + res.cause());
}
}));
}
}
I expect that when the consumer replies to the message, it will be received by the sender. However, I get a timeout:
Successfully sent reply
Failed to send reply.(TIMEOUT,-1) Timed out after waiting 30000(ms) for a reply. address: 2, repliedAddress: 1
Deployment:
public class ServiceLauncher {
private static Vertx vertx = Vertx.vertx();
public static void main(String[] args) {
vertx.deployVerticle(new Consumer(), res -> {
if (res.succeeded()) {
System.out.println("Verticle " + Consumer.NAME + " deployed.");
vertx.deployVerticle(new Sender());
System.out.println("Verticle " + Sender.NAME + " deployed.");
} else {
System.out.println("Verticle " + Consumer.NAME + " not deployed.");
}
});
}
What am I doing wrong? Thanx in advance
Update: The problem is in msg.reply() - the consumer doesn't reply to the message but I can't still figure out why.
The timeout occurs not in the sender of the request, but in its recipient.
Handler, defined in msg.reply(), waits for next reply from the sender. It is not a handler, confirming just send status.
And handler in Sender's eventBus.send() also fires when sender receives a reply.
Just remove handler in msg.reply() and modify handler eventBus.send() in Sender in the same manner:
public class Sender extends AbstractVerticle {
public static final String NAME = "SENDER";
#Override
public void start() {
EventBus eventBus = vertx.eventBus();
eventBus.send(Constants.ADDRESS, "Hello from sender", res -> {
if (res.succeeded()) {
System.out.println("Successfully received reply: " + res.result().body());
} else {
System.out.println("Failed to send reply." + res.cause());
}
});
}
}
and
public class Consumer extends AbstractVerticle {
public static final String NAME = "CONSUMER";
#Override
public void start() {
final EventBus eventBus = vertx.eventBus();
eventBus.consumer(Constants.ADDRESS, msg -> {
System.out.println("Message received");
msg.reply("Hi from consumer.");
});
}
}
And after execute you'll see:
Verticle CONSUMER deployed.
Verticle SENDER deployed.
Message received
Successfully received reply: Hi from consumer.
I had a similar issue. In my case, I was sending a non JsonObject reply. The message has to be replied to with a valid JsonObject -- not JsonArray or any other. This looks the default behaviour although the doc mentions JsonObject is not required. But the real problem in your original code snippet is that you have specified a handler for the reply's reply. The Consumer is replying successfully but the consumer is not getting a reply from Sender. See below with comment.
#Override
public void start() {
eventBus = vertx.eventBus();
eventBus.consumer(Constants.ADDRESS, msg -> msg.reply("Hi from consumer.", res -> {
if (res.succeeded()) { //this is expecting a response from Sender which never does so this will never execute.
System.out.println("Successfully sent reply");
} else { //it's not failing either so this will not execute either
System.out.println("Failed to send reply." + res.cause());
}
}));
}

What is the proper way of enabling Stream Management in smack 4.1.1

I have search every for the method used in enabling stream management in smack and nothing is working for me
This function isSmAvailable() always return false, am using prosody as the XMPP server in which the smacks[mod_smacks] is installed and enabled below is my code
XMPPTCPConnectionConfiguration.Builder configureBuilder = XMPPTCPConnectionConfiguration.builder();
configureBuilder.setServiceName(Config.XMPP_HOST);
configureBuilder.setHost(HOST);
//configureBuilder.allowEmptyOrNullUsernames();
configureBuilder.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
//configureBuilder.setDebuggerEnabled(true);
SmackConfiguration.DEBUG = true;
xmppConnection = new XMPPTCPConnection(configureBuilder.build());
Roster.setDefaultSubscriptionMode(Roster.SubscriptionMode.accept_all);
XMPPTCPConnection.setUseStreamManagementResumptiodDefault(true);
//PingManager
xmppConnection.setUseStreamManagement(true);
xmppConnection.setUseStreamManagementResumption(true);
ReconnectionManager reconnectionManager = ReconnectionManager.getInstanceFor(xmppConnection);
reconnectionManager.enableAutomaticReconnection();
try {
MyLog.w("Connecting to xmpp server");
xmppConnection.setPacketReplyTimeout(100000);
xmppConnection.connect();
//xmppConnection.sendSmAcknowledgement();
if (xmppConnection.isSmEnabled()) {
MyLog.w("stream M is enabled");
} else {
MyLog.w("stream M is not enabled");
}
if (xmppConnection.isSmAvailable()) {
MyLog.w("stream M available");
} else {
MyLog.w("stream M is not available");
}
//xmppConnection.
xmppConnection.addConnectionListener(new ConnectionListener() {
#Override
public void connected(XMPPConnection xmppConnection) {
//logger.warning("Connected to server successfully");
MyLog.w("Connected to server");
}
#Override
public void authenticated(XMPPConnection xmppConnect, boolean b) {
//logger.warning("Nice it is authenticated too");
MyLog.w("Finally logged into the server");
}
#Override
public void connectionClosed() {
//logger.warning("Connected to server failed");
}
#Override
public void connectionClosedOnError(Exception e) {
//logger.warning(e.getMessage());
MyLog.w("Connection close on error" + e.getMessage());
}
#Override
public void reconnectionSuccessful() {
//I think here we need to relogin the user
MyLog.w("Reconnected successfully ....thanks to RC");
}
#Override
public void reconnectingIn(int i) {
}
#Override
public void reconnectionFailed(Exception e) {
MyLog.w("Reconnection Failed " + e.getMessage());
}
});
} catch (Exception e) {
MyLog.w("connected-error" + e.getMessage());
}
I tried adding streamFeature for stream management using
xmppConnection.addStreamFeature() but it tells me that the function is private
and also through ProviderManager.addStreamFeature(element, namespace, provider) is also not working
Can you please help me to figure this out or there is something am doing wrong here
Thanks
Check your ejabbered config file for stream management is enable or not.
stream_management: true
resend_on_timeout: true
resume_timeout: 300
In android code you just add to below line to enable stream management in your app.
static{
XMPPTCPConnection.setUseStreamManagementDefault(true);
XMPPTCPConnection.setUseStreamManagementResumptionDefault(true);
}
This piece of code is working for me having ejabbered on server side--
XMPPTCPConnectionConfiguration connConfig = XMPPTCPConnectionConfiguration.builder()
.setHost(HOST)
.setPort(PORT)
.setDebuggerEnabled(true)
.setSecurityMode(SecurityMode.disabled)
.setUsernameAndPassword(USERNAME, PASSWORD)
.setServiceName(SERVICE).build();
XMPPTCPConnection connection = new XMPPTCPConnection(connConfig);
connection.setUseStreamManagement(true);
connection.setPacketReplyTimeout(TIME_OUT);
connection.connect();
connection.login();

XMPP: Smack client not receiving chat message

I've been struggling with XMPP chatting a lot through Smack and Openfire server.
My problem is as follows:
Whenever a user sends a message to another user, the message is received correctly at the other user. But any reply doesn't show up at the sender of the first message.
So User 1 sends to User 2 successfully. User 2 is then unable to send to User 1 any reply.
On the other hand, if I restart and let the users login again, User 2 can send to User 1 but not vice versa.
What I'm trying to say is that only the initiator of the chat can send a message, the receiver cannot reply back.
My code looks like this
package xmpp;
public class XMPPClient{
private static final int packetReplyTimeout = 500; // millis
private XMPPConnection connection;
private ChatManager chatManager;
private MessageListener messageListener;
private ConnectionConfiguration config;
private MyTimer t = MyTimer.getInstance();
private ArrayList<String> threadPool = new ArrayList<String>();
public XMPPClient()
{
SmackConfiguration.setPacketReplyTimeout(packetReplyTimeout);
//define openfire server information
config = new ConnectionConfiguration("localhost",5222);
config.setSASLAuthenticationEnabled(false);
config.setSecurityMode(SecurityMode.disabled);
connection = new XMPPConnection(config);
//connect to server
t.start("Connecting to server...");
try {
connection.connect();
} catch (XMPPException e) {
System.err.println("Failed to connect to server! Connect to VPN!\t"+e.getMessage());
System.exit(0);
}
t.end("Connection took ");
//setup chat mechanism
chatManager = connection.getChatManager();
chatManager.addChatListener(
new ChatManagerListener() {
#Override
public void chatCreated(Chat chat, boolean createdLocally)
{
if (!createdLocally)
chat.addMessageListener(new MyMessageListener());
}
});
}
public boolean login(String userName, String password, String resource) {
t.start("Logging in...");
try {
if (connection!=null && connection.isConnected())
connection.login(userName, password, resource);
//set available presence
setStatus(true);
}
catch (XMPPException e) {
if(e.getMessage().contains("auth")){
System.err.println("Invalid Login Information!\t"+e.getMessage());
}
else{
e.printStackTrace();
}
return false;
}
t.end("Logging in took ");
return true;
}
public void setStatus(boolean available) {
if(available)
connection.sendPacket(new Presence(Presence.Type.available));
else
connection.sendPacket(new Presence(Presence.Type.unavailable));
}
public void sendMessage(String message, String buddyJID) throws XMPPException {
System.out.println(String.format("Sending mesage '%1$s' to user %2$s", message, buddyJID));
boolean chatExists = false;
Chat c = null;
for(String tid : threadPool)
{
if((c = chatManager.getThreadChat(tid)) != null)
{
if(c.getParticipant().equals(buddyJID))
{
if(checkAvailability(buddyJID))
{
chatExists = true;
break;
}
else
{
threadPool.remove(tid);
break;
}
}
}
}
if (chatExists)
{
Chat chat = c;
chat.sendMessage(message);
}
else
{
Chat chat = chatManager.createChat(buddyJID, messageListener);
threadPool.add(chat.getThreadID()); System.out.println(chat.getThreadID());
chat.sendMessage(message);
}
}
public void createEntry(String user, String name) throws Exception {
System.out.println(String.format("Creating entry for buddy '%1$s' with name %2$s", user, name));
Roster roster = connection.getRoster();
roster.createEntry(user, name, null);
}
public boolean checkAvailability(String jid)
{
System.out.print("Checking availability for: "+jid+"=");
System.out.println(connection.getRoster().getPresence(jid).isAvailable());
return connection.getRoster().getPresence(jid).isAvailable();
}
public void disconnect() {
if (connection!=null && connection.isConnected()) {
setStatus(false);
connection.disconnect();
}
}
}
import org.jivesoftware.smack.packet.Message;
public class MyMessageListener implements MessageListener {
#Override
public void processMessage(Chat chat, Message message) {
String from = message.getFrom();
String body = message.getBody();
System.out.println(String.format("Received message '%1$s' from %2$s", body, from));
}
}
I'm not sure what the problem is. Any suggestions? Sample code?
Thanks <3
I am not sure if this will help you but I can get reply with this code:
public void chat(String AddressedUser) throws NotConnectedException {
//Create username whom we want to send a message
String userToSend = AddressedUser + "#" + serverDomain;
ChatManager chatmanager = ChatManager.getInstanceFor(connection);
Chat newChat = chatmanager.createChat(userToSend , new MessageListener() {
#Override
public void processMessage(Chat chat, Message message ) {
// TODO Auto-generated method stub
System.out.println("Received message: " + message);
}
});
try {
newChat.sendMessage("Hey");
}
catch (XMPPException e) {
System.out.println("Error Delivering block");
}
}
I am sending "Hey" then what ever other user writes I will see in my logcat.
You haven't specified what the receiver is, for instance, if it is an existing client (like Spark for instance), or more custom code. This would be helpful, as would knowing what version of Smack you are using.
That particular code has several issues with it.
It keeps creating new Chat objects for every message sent, instead of
simply reusing the same chat.
There is no ChatManagerListener registered to handle new Chat messages that are not tied to an existing chat.
the is code is very complicated and it seems is meant only to send msgs.
Here is a sample code that works perfectly, both sending and receiving:
http://www.javaprogrammingforums.com/java-networking-tutorials/551-how-write-simple-xmpp-jabber-client-using-smack-api.html

how to receive sms in netbeans mobile application

I am developing a mobile application in net-beans that will send and receive SMS, I'm done with sending text but I don't know how to receive SMS in NetBeans mobile application ?
WMA (Wireless Messaging API) is a wireless messaging api defined in MIDP 2.0. These apis are designed to handle text, binary and multipart messages. To make a connection, the application obtains an object implementing the MessageConnection from the Connector class by providing an URL connection string that identifies the address.
/* Make a connection */
public boolean connectSMSServer()
{
try
{
messageConnection messageConnection =
(MessageConnection)Connector.open("sms://:" + port);
messageConnection.setMessageListener(this);
}
catch (Exception e) {
}
}
/* Send text message */
public void sendTextmessage(String address,String message)
{
try
{
//creates a new TextMessage
TextMessage textMessage = (TextMessage)messageConnection.newMessage(
MessageConnection.TEXT_MESSAGE, address);
textMessage.setPayloadText(message);
messageConnection.send(textMessage);
}
catch (Exception e) {
}
}
/* Recieve text message */
public void receiveTextMessage()
{
try
{
Message message = messageConnection.receive();
if (message instanceof TextMessage)
{
TextMessage textMessage = (TextMessage)message;
}
else
{
//Message can be binary or multipart
}
}
catch (Exception e) {
}
}
/* Notify Incoming Message */
public synchronized void notifyIncomingMessage(MessageConnection conn)
{
//notiy thread of incoming message
synchronized (this)
{
notify();
}
}
/* Close Connection */
public void closeConnection()
{
if (messageConnection != null)
{
try
{
messageConnection.setMessageListener(null);
messageConnection.close();
}
catch (Exception e) {
}
}
}
}
When you are coding for Receiving SMS, you need to listen to one particular port. J2ME Application can not read directly from the inbox.