WeChat chat source code analysis-Logon

Source: Internet
Author: User

The core file of WeChat chat is jsjac. js.

After reading this file, we can basically run webim. Let's talk about jsjac:

Jsjac is called jsjac-Javascript. Jabber Client library, which is a client library written in JavaScript.

Its purpose is to facilitate the implementation of the Web-based Jabber/XMPP client.

Jsjac features:
1. Object-oriented Interfaces
2. Communication uses the httprequest object, that is, Ajax technology.
3. Good compatibility: It is compatible with most ajax/JS frameworks, such as prototype, mootools, jquery, dojo and Yui! And so on

1. login operation

In index.html, only front-end verification is performed and no connection is made to the openfire server.

/* * check if user want's to register new account and things */function loginCheck(form) {if (form.jid.value == '') {alert("You need to supply a username");return false;}if (form.pass.value == '') {alert("You need to supply a password");return false;}if (document.getElementById('tr_server').style.display != 'none') {var val = document.getElementById('server').value;if (val == '') {alert("You need to supply a jabber server");return false;}JABBERSERVER = val;}jid = form.jid.value + "@" + JABBERSERVER + "/";if (form.res.value != '')jid += form.res.value;elsejid += DEFAULTRESOURCE;if (!isValidJID(jid))return false;if (jwchats[jid] && !jwchats[jid].closed) {jwchats[jid].focus();return false;}pass = form.pass.value;register = form.register.checked;prio = form.prio[form.prio.selectedIndex].value;connect_port = form.connect_port.value;connect_host = form.connect_host.value;connect_secure = form.connect_secure.checked;jwchats[jid] = window.open('jwchat.html', makeWindowName(jid),'width=620,height=590,resizable=yes');return false;}

After the verification is passed, connect to the jwchat.html file and use the init () method to connect to the server.

/************************************************************************ *                           ******  INIT  ******* ************************************************************************ */var con, Debug, srcW;function init() {  /* initialise debugger */  if (!Debug || typeof(Debug) == 'undefined' || !Debug.start) {    if (typeof(Debugger) != 'undefined'){      Debug = new Debugger(DEBUG_LVL,'jwchat' + cutResource(jid));}    else {      Debug = new Object();      Debug.log = function() {};      Debug.start = function() {};    }  }  if (DEBUG &&  (!USE_DEBUGJID || DEBUGJID == cutResource(jid)))    Debug.start();    Debug.log("jid: "+jid+"\npass: "+pass,2);  /* get some refs to static elements */  statusLed = frames["jwc_main"].document.getElementById('statusLed');  statusMsg = frames["jwc_main"].document.getElementById('statusMsg');  fmd = frames["jwc_main"].iRoster.document;    /* set title */  document.title = "JointSky Messenger - " + nick;  /* set nick */  frames["jwc_main"].document.getElementById('myNickname').innerHTML = nick;    /* set unit 2012.8.8 dml@wip Notice:This value should be catch from userInfo which is stored in openfire*/  frames["jwc_main"].document.getElementById('unit').innerHTML = "(ch)";      /* init empty roster */  roster = new Roster();    /* ***   * create new connection   */  var oArg = {oDbg: Debug, httpbase: HTTPBASE, timerval: timerval};    if (BACKEND_TYPE == 'binding')    con = new JSJaCHttpBindingConnection(oArg);  else    con = new JSJaCHttpPollingConnection(oArg);    /* register handlers */  con.registerHandler('iq',handleIQSet);  con.registerHandler('presence',handlePresence);  con.registerHandler('message',handleMessage);  con.registerHandler('message',handleMessageError);  con.registerHandler('ondisconnect',handleDisconnect);  con.registerHandler('onconnect',handleConnected);  con.registerHandler('onerror',handleConError);    /* connect to remote */  oArg = {domain:JABBERSERVER,username:jid.substring(0,jid.indexOf('@')),resource:jid.substring(jid.indexOf('/')+1),pass:pass,register:register}    if (BACKEND_TYPE == 'binding') {    if (opener.connect_port && !isNaN(opener.connect_port))      oArg.port = opener.connect_port;    if (opener.connect_host && opener.connect_host != '')      oArg.host = opener.connect_host;    if (opener && opener.connect_secure)      oArg.secure = true;  }  con.connect(oArg);}

It is clear that the connection operation is completed by jsjachttpbindingconnection or jsjachttppollingconnection (jsjac. JS is an object-oriented interface, so you can understand these two methods according to OO ideas)

Jsjachttpbindingconnection source code:

function JSJaCHttpBindingConnection(oArg) {    this.base = JSJaCConnection;    this.base(oArg);    this._hold = JSJACHBC_MAX_HOLD;    this._inactivity = 0;    this._last_requests = new Object();    this._last_rid = 0;    this._min_polling = 0;    this._pause = 0;    this._wait = JSJACHBC_MAX_WAIT;    this.connect = JSJaCHBCConnect;    this.disconnect = JSJaCHBCDisconnect;    this.inherit = JSJaCHBCInherit;    this.isPolling = function() {        return (this._hold == 0)    };    this.setPollInterval = function(timerval) {        if (!timerval || isNaN(timerval)) {            this.oDbg.log("Invalid timerval: " + timerval, 1);            return - 1;        }        if (!this.isPolling()) this._timerval = 100;        else if (this._min_polling && timerval < this._min_polling * 1000) this._timerval = this._min_polling * 1000;        else if (this._inactivity && timerval > this._inactivity * 1000) this._timerval = this._inactivity * 1000;        else this._timerval = timerval;        return this._timerval;    };    this._getRequestString = JSJaCHBCGetRequestString;    this._getFreeSlot = function() {        for (var i = 0; i < this._hold + 1; i++) if (typeof(this._req[i]) == 'undefined' || typeof(this._req[i].r) == 'undefined' || this._req[i].r.readyState == 4) return i;        return - 1;    }    this._getHold = function() {        return this._hold;    }    this._getStreamID = JSJaCHBCGetStreamID;    this._getSuspendVars = function() {        return ('host,port,secure,_rid,_last_rid,_wait,_min_polling,_inactivity,_hold,_last_requests,_pause').split(',');    }    this._handleInitialResponse = JSJaCHBCHandleInitialResponse;    this._prepareResponse = JSJaCHBCPrepareResponse;    this._reInitStream = JSJaCHBCReInitStream;    this._resume = function() {        if (this._pause == 0 && this._rid >= this._last_rid) this._rid = this._last_rid - 1;        this._process();        this._inQto = setInterval("oCon._checkInQ();", JSJAC_CHECKINQUEUEINTERVAL);        this._interval = setInterval("oCon._checkQueue()", JSJAC_CHECKQUEUEINTERVAL);    }    this._setHold = function(hold) {        if (!hold || isNaN(hold) || hold < 0) hold = 0;        else if (hold > JSJACHBC_MAX_HOLD) hold = JSJACHBC_MAX_HOLD;        this._hold = hold;        return this._hold;    };    this._setupRequest = JSJaCHBCSetupRequest;    this._suspend = function() {        if (this._pause == 0) return;        var slot = this._getFreeSlot();        this._req[slot] = this._setupRequest(false);        var reqstr = "<body pause='" + this._pause + "' xmlns='http://jabber.org/protocol/httpbind' sid='" + this._sid + "' rid='" + this._rid + "'";        if (JSJAC_HAVEKEYS) {            reqstr += " key='" + this._keys.getKey() + "'";            if (this._keys.lastKey()) {                this._keys = new JSJaCKeys(hex_sha1, this.oDbg);                reqstr += " newkey='" + this._keys.getKey() + "'";            }        }        reqstr += ">";        while (this._pQueue.length) {            var curNode = this._pQueue[0];            reqstr += curNode;            this._pQueue = this._pQueue.slice(1, this._pQueue.length);        }        reqstr += "</body>";        var abortTimerID = setTimeout("oCon._req[" + slot + "].r.abort();", 5000);        this.oDbg.log("Disconnecting: " + reqstr, 4);        this._req[slot].r.send(reqstr);        clearTimeout(abortTimerID);    }}

Jsjachttppollingconnection source code:

function JSJaCHttpPollingConnection(oArg) {    this.base = JSJaCConnection;    this.base(oArg);    JSJACPACKET_USE_XMLNS = false;    this.connect = JSJaCHPCConnect;    this.disconnect = JSJaCHPCDisconnect;    this.isPolling = function() {        return true;    };    this._getFreeSlot = function() {        if (typeof(this._req[0]) == 'undefined' || typeof(this._req[0].r) == 'undefined' || this._req[0].r.readyState == 4) return 0;        else return - 1;    }    this._getRequestString = JSJaCHPCGetRequestString;    this._getStreamID = JSJaCHPCGetStream;    this._getSuspendVars = function() {        return new Array();    }    this._prepareResponse = JSJaCHPCPrepareResponse;    this._reInitStream = JSJaCHPCReInitStream;    this._resume = function() {        this._process(this._timerval);        this._interval = setInterval("oCon._checkQueue()", JSJAC_CHECKQUEUEINTERVAL);        this._inQto = setInterval("oCon._checkInQ();", JSJAC_CHECKINQUEUEINTERVAL);    }    this._setupRequest = JSJaCHPCSetupRequest;    this._suspend = function() {};}

 

When logging on, you need to analyze the oarg Parameter

 var oArg = {oDbg: Debug, httpbase: HTTPBASE, timerval: timerval};

Among them, debug is a debugger instance, and there is a declaration in Init ()

Debug = new Debugger(DEBUG_LVL,'jwchat ' + cutResource(jid));}

Debugger in debugger. js

function Debugger(lvl,id) {this.lvl = lvl || 0;if (this.lvl > DEBUGGER_MAX_LEVEL)this.lvl = DEBUGGER_MAX_LEVEL;this.id = id || '';this.debugMsgs = new Array();this.log = DebugLog;this.setLevel = DebugSetLevel;this.start = DebugStart;this.stop = DebugStop;

Httpbase and timerval are set in config. JS, which can be set as needed by the project.

As described above, open the openfire server, run login http: // 127.0.0.1: 9090/user-summary.jsp, the online user list to view the information shows that the login is normal.

 

It should be noted that the service will automatically prompt a connection timeout if the service remains static for about 5-6 minutes. In this case, you need to modify the org. jivesoftware. openfire. NiO. clientconnectionhandler class and XMPP. Client. Idle attribute.

@ Overrideint getmaxidletime () {// sets the default timeout value to 6 minutes. // return jiveglobals. getintproperty ("XMPP. client. idle ", 6*60*1000)/1000; // set the timeout time to 30 minutes return jiveglobals. getintproperty ("XMPP. client. idle ", 30*60*1000)/1000 ;}

Alternatively, enter URL: http: // 127.0.0.1: 9090/client-connections-settings.jsp to set

Alternatively, directly modify the idle value in the ofproperty table.

 

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.