Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to effectively use persistent XMPP with android

I want to develop an instant messaging application. GCM, for pushing data is a popular(and efficient) way to go , if you are on android, but I am not using it due to the following reasons:

  1. It deletes more than 100 undelivered messages.
  2. It will not work on devices that do not have google apps.

Instead, I decided on setting up a traditional XMPP server (openFire), and I am using the Smack api(TCP connection) to connect. So far, it is going well , but I have a few concerns.

This is a small test code I wrote(it runs in a service):

    Log.d("TAG","service has started");
        SmackConfiguration.setDefaultPacketReplyTimeout(10000);
        XMPPTCPConnectionConfiguration config = XMPPTCPConnectionConfiguration.builder()
                .setUsernameAndPassword("admin", "football100")
                .setServiceName("harsh-pc")
                .setHost("192.168.0.200")
                .setPort(5222).setSecurityMode(ConnectionConfiguration.SecurityMode.disabled)
                .build();

        final AbstractXMPPConnection conn2 = new XMPPTCPConnection(config);
        try {
            conn2.connect();

            conn2.login();

            Presence presence = new Presence(Presence.Type.available);
            presence.setStatus("online");
            // Send the packet (assume we have an XMPPConnection instance called "con").
            conn2.sendStanza(presence);

        } catch (SmackException | IOException | XMPPException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            Log.d("TAG", e.toString());
        }
StanzaFilter filter=new StanzaFilter() {
    @Override
    public boolean accept(Stanza stanza) {
        return true;
    }
};
        StanzaListener listener= new StanzaListener() {
            @Override
            public void processPacket(Stanza packet) throws SmackException.NotConnectedException {
                Log.d("TAG","recevied stuff");
                ChatManager chatmanager = ChatManager.getInstanceFor(conn2);


                Chat newChat = chatmanager.createChat("harsh@harsh-pc");
                newChat.sendMessage("Reply :) ");
            }
        };

        conn2.addAsyncStanzaListener(listener,filter);
        ChatManager chatmanager = ChatManager.getInstanceFor(conn2);


        Chat newChat = chatmanager.createChat("harsh@harsh-pc");

        try {
            Random r=new Random();

               // newChat.sendMessage(Integer.toString(r.nextInt()));
            Thread.sleep(1500);


            }
        catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            Log.d("TAG",e.toString());
        }
    }
}).start();


final Thread sleeper=new Thread(new Runnable() {
    @Override
    public void run() {
        for(;;){
            try {
                Thread.sleep(100000);
                Log.d("TAG","SLEEPI");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
});sleeper.start();

Notice the last part of this snippet. I have to run an infinite loop so that I can keep listening for incoming packets (if I dont include this code, I am not able to intercept any incoming packets).

My questions are:

  1. Is this method going to take tremendous amounts of battery?
  2. Will this method prevent the device from sleeping?
  3. Is there a better way to get things done (without using GCM) ?
  4. Is there a way to integrate GCM with OPENFIRE ?
like image 450
harveyslash Avatar asked May 15 '15 16:05

harveyslash


1 Answers

We had same requirement in the past ,where We provided an external chat functionality with our application, for which we used XMPP [ using aSmack],

It is good know that that you have figure out you need to use a external service in order to make an persistence xmpp connection with server ,but make sure service should be background service and make it sticky service.

Either Use GCM or XMPP is actually Dependant on how you are designing your system,you can use both of them in your application in order to make it more stable and of cause more complex!!!!!

Still its a long shot to make such a complex system you can always go with simple solution available thats XMPP.

Is this method going to take tremendous amounts of battery? It should not!!! as you are using default ping interval here(which is actually 30 min),it should not consume more battery. if you had used ping interval less than 5 min then you should worried about battery drainage problem !!!

Will this method prevent the device from sleeping? As per my understanding ,You are using TCP connection here unless there is no data on input-stream device can go into the sleep ,as soon as some data arrive device will wake up and or you send some data on same socket [such like heartbeat/ping] to keep cpu awake .but still this behavior can vary as per different mobile manufacture.

Is there a better way to get things done (without using GCM) ? XMPP is always a strong alternative of gcm,as long as you know what are you really looking for.You can always try to optimize your system for batter output.

Is there a way to integrate GCM with OPENFIRE ? I am confused here what you really want to ask here !!! gcm(CCS) is google implementation of XMPP server you can always create a XMPP client using smack but to integrate GCM with Openfire means you are looking at server to server communication ,which is out of scope of you application requirements as per my understanding!!!!

Below are some useful links which can help you out with your research

Should applications using aSmack use foreground Services?

How to keep a XMPP connection stable on Android with (a)smack?

How To Create Service In Android Which Makes Persist Xmpp Connection With XMPP Server?

Keep XMPP connection (using asmack) alive on Android

like image 136
Dev Avatar answered Oct 14 '22 18:10

Dev