Based on the XMPP protocol and openfire server, the server handles the problem of being pushed offline or failed to log on for the second time due to network disconnection.

Source: Internet
Author: User
Tags vcard

Recently, many people have encountered some problems in instant messaging applications based on the oenfire server and asmack open-source framework. In the process of solving the problem, I found that many of my colleagues were wrong, so I decided to write the next blog to inform my colleagues who are worried about the problem.

First of all, we offer a log class, so you don't have to worry about writing tags every time. This class uses the hunger style of the singleton mode. If you are interested, you can change it to the perfect style:

Public class logutil {private final static string tag = "[what name do you want to obtain?]"; public static int loglevel = log. verbose; // public static int loglevel = log. error; // Private Static Boolean logflag = true; Private Static logutil logger = new logutil (); public static logutil getlogger () {return logger;} private logutil () {} private string getfunctionname () {stacktraceelement [] STS = thread. currentthrea D (). getstacktrace (); If (STS = NULL) {return NULL;} For (stacktraceelement ST: STS) {If (St. isnativemethod () {continue;} If (St. getclassname (). equals (thread. class. getname () {continue;} If (St. getclassname (). equals (this. getclass (). getname () {continue;} return "[" + thread. currentthread (). getname () + ":" + st. getfilename () + ":" + st. getlinenumber () + "]";} return NULL;} public Void I (Object Str) {If (! Appconfig. Debug) return; If (loglevel <= log. info) {string name = getfunctionname (); If (name! = NULL) {log. I (TAG, name + "-" + Str);} else {log. I (TAG, str. tostring () ;}} public void V (Object Str) {If (! Appconfig. Debug) return; If (loglevel <= log. verbose) {string name = getfunctionname (); If (name! = NULL) {log. V (TAG, name + "-" + Str);} else {log. V (TAG, str. tostring () ;}} public void W (Object Str) {If (! Appconfig. Debug) return; If (loglevel <= log. Warn) {string name = getfunctionname (); If (name! = NULL) {log. W (TAG, name + "-" + Str);} else {log. W (TAG, str. tostring () ;}} public void E (Object Str) {If (! Appconfig. Debug) return; If (loglevel <= log. Error) {string name = getfunctionname (); If (name! = NULL) {log. E (TAG, name + "-" + Str);} else {log. E (TAG, str. tostring () ;}} public void E (exception ex) {If (! Appconfig. debug) return; If (loglevel <= log. error) {log. E (TAG, "error", ex) ;}} public void D (Object Str) {If (! Appconfig. Debug) return; If (loglevel <= log. Debug) {string name = getfunctionname (); If (name! = NULL) {log. D (TAG, name + "-" + Str) ;}else {log. D (TAG, str. tostring ());}}}}

Next, we need a singleton class to manage xmppconnection. This time it seems to be lazy. Why is Singleton used? The reason is that you don't want your application to have multiple xmppconnection objects, the error may be due to escape. The X represents (":" + x + ":")

Public class xmppconnmanager {public static int server_port = 5222; // you can set public static string server_host = "42.121.17.115" on openfire "; // The IP address of your openfire server public static string SERVER_NAME = "helloworld"; // set the server name Private Static xmppconnection connection = NULL when openfire is enabled; Private Static xmppconnmanager connmanager = NULL; public static xmppconnmanager getinstance () {If (connmanager = NULL) {con Nmanager = new xmppconnmanager ();} return connmanager;} private void openconnection () {try {If (null = connection |! Connection. isauthenticated () {xmppconnection. debug_enabled = true; // enable debug mode // configure the connection/* connectionconfiguration Config = new connectionconfiguration (server_host, server_port, SERVER_NAME); */connectionconfiguration Config = new connectionconfiguration (server_host, server_port); config. setreconnectionallowed (true); config. setsendpresence (false);/* config. setsaslauthenticationenabled (false); Conf IG. setsecuritymode (securitymode. disabled); config. setcompressionenabled (false); */connection = new xmppconnection (config); connection. connect (); // connect to the server // configure various provider configureconnection (providermanager. getinstance () ;}} catch (xmppexception Xe) {Xe. printstacktrace () ;}}/*** create connection */Public xmppconnection getconnection () {If (connection = NULL) {openconnection ();} return connection ;}/* ** Close connection */Public void closeconnection () {If (connection! = NULL) {connection. disconnect (); connection = NULL; logutil. getlogger (). E ("closeconnection operation in rows") ;}}/*** XMPP configuration */private void configureconnection (providermanager pm) {// Private Data Storage PM. addiqprovider ("query", "jabber: IQ: Private", new privatedatamanager. privatedataiqprovider (); // time try {PM. addiqprovider ("query", "jabber: IQ: time", class. forname ("org. jivesoftware. smackx. packet. time ");} catch (exception e) {e. printstacktrace ();} // roster exchange PM. addextensionprovider ("X", "jabberroster", new rosterexchangeprovider (); // message events PM. addextensionprovider ("X", "jabberevent", new messageeventprovider (); // chat state PM. addextensionprovider ("active", "http://jabber.org/protocol/chatstates", new chatstateextension. provider (); PM. addextensionprovider ("composing", "http://jabber.org/protocol/chatstates", new chatstateextension. provider (); PM. addextensionprovider ("paused", "http://jabber.org/protocol/chatstates", new chatstateextension. provider (); PM. addextensionprovider ("inactive", "http://jabber.org/protocol/chatstates", new chatstateextension. provider (); PM. addextensionprovider ("gone", "http://jabber.org/protocol/chatstates", new chatstateextension. provider (); // xhtml pm. addextensionprovider ("html", "http://jabber.org/protocol/xhtml-im", new xhtmlextensionprovider (); // group chat invitations PM. addextensionprovider ("X", "jabberconference", new groupchatinvitation. provider (); // service discovery # items // parse the room list PM. addiqprovider ("query", "http://jabber.org/protocol/disco#items", new discoveritemsprovider (); // service discovery # info // information PM for a room. addiqprovider ("query", "http://jabber.org/protocol/disco#info", new discoverinfoprovider (); // data forms PM. addextensionprovider ("X", "jabberdata", new dataformprovider (); // muc user PM. addextensionprovider ("X", "http://jabber.org/protocol/muc#user", new mucuserprovider (); // muc admin PM. addiqprovider ("query", "http://jabber.org/protocol/muc#admin", new mucadminprovider (); // muc owner PM. addiqprovider ("query", "http://jabber.org/protocol/muc#owner", new mucownerprovider (); // delayed delivery PM. addextensionprovider ("X", "jabberdelay", new delayinformationprovider (); // version try {PM. addiqprovider ("query", "jabber: IQ: version", class. forname ("org. jivesoftware. smackx. packet. version ");} catch (classnotfoundexception e) {// not sure what's happening here .} // vCard PM. addiqprovider ("vCard", "vCard-Temp", new vcardprovider (); // offline message requests PM. addiqprovider ("offline", "http://jabber.org/protocol/offline", new offlinemessagerequest. provider (); // offline message indicator PM. addextensionprovider ("offline", "http://jabber.org/protocol/offline", new offlinemessageinfo. provider (); // last activity PM. addiqprovider ("query", "jabber: IQ: Last", new lastactivity. provider (); // user search PM. addiqprovider ("query", "jabber: IQ: Search", new usersearch. provider (); // sharedgroupsinfo PM. addiqprovider ("sharedgroup", "http://www.jivesoftware.org/protocol/sharedgroup", new sharedgroupsinfo. provider (); // JEP-33: Extended stanza addressing PM. addextensionprovider ("addresses", "http://jabber.org/protocol/address", new multipleaddressesprovider (); PM. addiqprovider ("Si", "http://jabber.org/protocol/si", new streaminitiationprovider (); PM. addiqprovider ("query", "jabber: IQ: Privacy", new privacyprovider (); PM. addiqprovider ("command", "http://jabber.org/protocol/commands", new adhoccommanddataprovider (); PM. addextensionprovider ("malformed-action", "http://jabber.org/protocol/commands", new adhoccommanddataprovider. malformedactionerror (); PM. addextensionprovider ("Bad-locale", "http://jabber.org/protocol/commands", new adhoccommanddataprovider. badlocaleerror (); PM. addextensionprovider ("Bad-payload", "http://jabber.org/protocol/commands", new adhoccommanddataprovider. badpayloaderror (); PM. addextensionprovider ("Bad-sessionid", "http://jabber.org/protocol/commands", new adhoccommanddataprovider. badsessioniderror (); PM. addextensionprovider ("session-expired", "http://jabber.org/protocol/commands", new adhoccommanddataprovider. sessionexpirederror ());}}

Next, write a service class to listen to xmppconnecttion:

Public class messageservice extends Service {private logutil log = logutil. getlogger (); Private chatmanager cm; private offlinemessagemanager offlinemanager; public static xmppconnection con = NULL; static {try {class. forname ("org. jivesoftware. smack. reconnectionmanager ");} catch (exception e) {e. printstacktrace () ;}@ override public ibinder onbind (intent arg0) {return NULL ;}@ override public Vo Id oncreate () {super. oncreate () ;}@ suppresswarnings ("deprecation") @ override public void onstart (intent, int startid) {super. onstart (intent, startid); New thread (New runnable () {@ override public void run () {If (networkutil. netstate (messageservice. this )! = False) {con = xmppconnmanager. getinstance (). getconnection (); con. addconnectionlistener (New connectionlistener () {@ override public void connectionclosed () {log. E ("from connection listening, Conn closed normally") ;}@ override public void connectionclosedonerror (exception arg0) {// here is the event if (arg0.getmessage () triggered by abnormal network or broken line (). contains ("Conflict") {// dropped/* log. E ("from the connection listener, the Conn is not properly closed"); log. E ("abnormal close exception:" + arg0.getmessage (); log. E (con. isconnected (); * // close the connection. It is a good choice to close the connection and allow the user to log on again because the connection is crowded and offline. getinstance (). closeconnection (); // next, you can send a broadcast prompting the user to be congested and deprecated. Re-connection is easy, that is, re-login} else if (arg0.getmessage (). contains ("connection timed out") {// connection timeout // No operation will be performed, automatic reconnection will be implemented} @ override public void reconnectingin (INT arg0) {// The ongoing reconnect action. The arg0 parameter in it is a countdown number. If the number of failed connections increases, the number will increase, it starts with 9 logs. E ("from connection listening, Conn reconnection... "+ arg0) ;}@ override public void reconnectionfailed (exception arg0) {// reconnect failed log. E ("connection listening, Conn failed:" + arg0.getmessage () ;}@ override public void reconnectionsuccessful () {// when the network is disconnected, event Log triggered by reconnecting to the server. E ("connection listener, Conn reconnect successful ");}});}). start () ;}@ override public int onstartcommand (intent, int flags, int startid) {// todo auto-generated method stub return Super. onstartcommand (intent, flags, startid );}}

Disclaimer: The copyright of the EOE article belongs to the author and is protected by law. The following information must be included in the hyperlink for reprinting.

Author: I am a burning comet

Address: http://my.eoe.cn/699035/archive/4818.html

-------

The interpreter said: network switching in wireless testing is a very bad thing.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.