Keep XMPP connection(using smack) alive throughout application - android

I am using the XMPP Connection(using smack) for chat in android application.I have made the connection with openfire and also i can send and receive the message.But the problem is that when i go in the XMPPClient.java activity then it made the connection.So i cant get any message till not go in that activity.So how can made the connection at the starting and then reuse at other activity.Code is in this 2 links ConnectionSettings file and the chatscreen in which we can do chat.In this link the comment line is also my questions so please also see that comment.

Create global XMPPConnection object and Use below funciton and store in global XMPPConnection object and use that connection object everywhere. This is a sample gtalk example.
public XMPPConnection login() throws XMPPException {
ConnectionConfiguration config = new
ConnectionConfiguration("talk.google.com",5222,"gmail.com");
config.setSecurityMode(SecurityMode.required);
config.setTruststoreType("BKS");
config.setTruststorePath("/system/etc/security/cacerts.bks");
XMPPConnection connection = new XMPPConnection(config);
connection.connect();
connection.login(username, password);
Presence presence = new Presence(Presence.Type.available);
presence.setMode(Presence.Mode.available);
connection.sendPacket(presence);
try {
Thread.sleep(3000);
} catch (Exception ex) {
ex.printStackTrace();
}
return connection;
}

Related

Sending message from Android client to Java server

I am developing an Android application, and I need to send a message from the application to the Java Server.
Java Server works like this:
thread = new Thread(){
public void run(){
System.out.println("Server is running...");
try {
ServerSocket socket = new ServerSocket(7000);
while(true){
Socket s = socket.accept();
DataInputStream dis = new DataInputStream(s.getInputStream());
System.out.println("Received from client: " + dis.readUTF());
dis.close();
s.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
};
thread.start();
In my application I send the message in this way:
mt = new Thread() {
public void run() {
try {
Socket socket = new Socket("192.168.1.100", 7000);
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
dos.writeUTF(song_field.getText().toString());
dos.flush();
dos.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
};
mt.start();
Toast.makeText(context, "Your Message is sent. Thank you!", Toast.LENGTH_SHORT).show();
I can send the message with emulator and my phone successfully, since they are connected to the same wifi connection, but if the device is not connected to the same network, message is not sent to the server. I want everybody to be able to send message to my computer server regardless of their internet connection.
How can I fix this problem?
In general you'll need to use something like Web Sockets to achieve what you're trying to do where, as would typically be the case, client/server are on different networks. There are a few different Web Socket implementations e.g. https://medium.com/square-corner-blog/web-sockets-now-shipping-in-okhttp-3-5-463a9eec82d1#.w9hrc1icw
EDIT
I initially misread question and thought you were trying to asynchronously send message from server to client (which would require something like Web Sockets). If you are just making requests from client to server then a typical solution would be to expose REST API from your server (and using something like Retrofit to make requests from client).

Instantiate ConnectionConfiguration in Smack 4.1

I am implementing a chat feature in my android app. So I have installed an open fire server and Smack Client library and now I have written a code to connect with the server but I am getting an error which states that ConnectionConfiguration is an abstract class.So i cant instaniate. Could you give me some idea about the instantiation of ConnectionConfiguration in SMACK 4.1?
Try to use the example below:
XMPPTCPConnectionConfiguration.Builder config = XMPPTCPConnectionConfiguration.builder();
config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
config.setUsernameAndPassword(USER_ID+ "#" + DOMAIN, key);
config.setServiceName(DOMAIN);
config.setHost(DOMAIN);
config.setPort(PORT);
config.setDebuggerEnabled(true);
config.setSocketFactory(SSLSocketFactory.getDefault());
mConnection = new XMPPTCPConnection(config.build());
try {
mConnection.connect();
} catch (SmackException | IOException | XMPPException e) {
e.printStackTrace();
}

roster.createEntry throws internal server error (500) exception

I am trying to create a XMPP chat client using aSmack library for android.I am using openfire server that runs on localhost.
I am creating a XMPPConnection and logging in the user successfully but when I try to create a new roster entry for that connection it throws an internal server error
Presence presence = new Presence(Presence.Type.subscribe);
presence.setTo(requestedUser);
connection.sendPacket(presence);
try {
roster.createEntry(requestedUser+"#123", "nickname", null);
} catch (XMPPException e) {
Log.e("exception", e.getMessage().toString());
}
Through this piece of code I am trying to send a friend request to another user.
When you call roster.createEntry(), it will send request to your openfire server,and then the server will insert an new record into your ofRoster table in openfire database.
So insure that ofRoster table exists.

No response from the server error in ejabberd server

Now I am working with XMPP-chat for Android using ejabberd server.
When I am trying to connect to the server, it shows an error. But it works fine in openfire server.
I am using smack library.
Error log is given below:
04-21 20:34:16.824: I/XMPPChatDemoActivity(1929): [SettingsDialog] Connected to 10.0.2.2
04-21 20:34:21.932: E/XMPPChatDemoActivity(1929): Failed to log in as test3#eworks.com
04-21 20:34:21.932: E/XMPPChatDemoActivity(1929): No response from the server.
I found solution how to connect to gtalk and jabber.org with Smack 3.1.0:
Code for GTalk:
ConnectionConfiguration cc = new ConnectionConfiguration("talk.google.com", 5222, "gmail.com");
XMPPConnection connection = new XMPPConnection(cc);
try {
connection.connect();
// You have to put this code before you login
SASLAuthentication.supportSASLMechanism("PLAIN", 0);
// You have to specify your gmail addres WITH #gmail.com at the end
connection.login("some.account#gmail.com", "password", "resource");
// See if you are authenticated
System.out.println(connection.isAuthenticated());
} catch (XMPPException e1) {
e1.printStackTrace();
}
For jabber.org here is the code:
ConnectionConfiguration cc = new ConnectionConfiguration("jabber.org", 5222, "jabber.org");
XMPPConnection connection = new XMPPConnection(cc);
try {
connection.connect();
// You have to put this code before you login
SASLAuthentication.supportSASLMechanism("PLAIN", 0);
// You have to specify your Jabber ID addres WITHOUT #jabber.org at the end
connection.login("your.jabber", "password", "resource");
// See if you are authenticated
System.out.println(connection.isAuthenticated());
} catch (XMPPException e1) {
e1.printStackTrace();
}
With this code i can now connect to my local ejabberd and openfire server. I hope this will solve your problems.

Android, problems with SocketAddress and sockets. Reverse lookup?

i have a problem with Android. I am trying to connect to a server with a proxy with no luck.
I have this code that works fine on normal Java. It only defines a proxy server and creates a socket that would connect to google with that proxy. It sends a simple GET request and then shows the response.
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Socket;
import java.net.SocketAddress;
public class Main {
public static void main(String[] args) {
try{
//create the proxy info
SocketAddress socketAddress = new InetSocketAddress("78.137.18.67" , 8364);
Proxy proxy = new Proxy(Proxy.Type.SOCKS, socketAddress);
// create the socket with the proxy
Socket socket = new Socket(proxy);
// connect to some address and send/receive data
socket.connect(new InetSocketAddress("www.google.com", 80));
socket.getOutputStream().write("GET /index.html HTTP/1.1\r\nHost: www.google.com\r\n\r\n".getBytes("UTF-8"));
byte result[] = new byte[1024];
socket.getInputStream().read(result);
socket.close();
System.out.println(new String(result));
}catch(Exception e){
e.printStackTrace();
}
}
}
The problem with android, with a code similar like that, is that the InetSocketAddress is doing something strange. It seems that it does a reverse lookup of the given ip, and then the socket created with the proxy tries to connect with the resolved host name, in this case is 78-137-18-67.dynamic-pool.mclaut.net.
This would not be a problem (except on performance) if the socket could resolve the hostname back to the ip address. The fact is that this hostname cannot be resolved to ip address with my internet connection (i don't know if others can do). So the reverse lookup is working fine but the normal lookups fails, so when the socket tries to connect through the proxy it raises the following exception:
08-25 19:26:46.332: ERROR/Microlog(3526): 40274 SocketConnection
[ERROR] Error establishing connection java.net.SocketException: SOCKS
connection failed: java.net.UnknownHostException:
78-137-18-67.dynamic-pool.mclaut.net
So the question is, why it is trying to connect with the hostname if i gave the ip address? Is there any way to avoid this lookup? I have tried with createUnresolved of InetSocketAddress but in this case the socket hangs on connection.
Is not a waste of time, internet connection, etc, to do a reverse DNS lookup to get the hostname (if any), and later when the socket needs to connect, resolve again the host to an ip address?
NOTE: this code is an example, the real app do not perform any http request in this way. It uses binary data packets.
To prevent a reverse lookup, you can create the InetAddress with getByAddress(byte[]).
Then pass the InetAddress instance into the InetSocketAddress constructor.
Alternatively, use the factory method InetSocketAddress.createUnresolved(String,int)
Yes it seems that the particular constructor of InetSocketAddress does a reverse DNS lookup: http://mailinglists.945824.n3.nabble.com/Android-and-reverse-DNS-lookup-issues-td3011461.html
Also, it seems that this does not happen anymore on Android 2.3.4.
In android you have to do everything with background process so that you do not write code for socket in onCreate method directly you have to do this in background so that your ui does not hangs
something like this
new Thread(new Runnable() {
#Override
public void run() {
try {
client = new Socket(ipaddress, port);
printwriter = new PrintWriter(client.getOutputStream(), true);
InputStream is = client.getInputStream();
printwriter.write(msg);
printwriter.flush();
byte[] buffer = new byte[2046];
int read;
while ((read = is.read(buffer)) != -1) {
final String output = new String(buffer, 0, read);
);
printwriter.close();
}
});
}
Log.e("message", "message send");
} catch (UnknownHostException e2) {
e2.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
Log.d("Time out", "Time");
}

Categories

Resources