live wid knowledge :)

March 2008 - Posts

Synchornous communication of client (browser) and server (IIS)

To make communication between client and server, we use XMLHTTPRequest object, same object used in AJAX, CALLBACK techniques and where ever we have to send request to server from client (browser).

XMLHTTPRequest communicate with server asynchronously, means invoker/caller doesn't wait for completion of completion of that function/subroutine/method, which it called so proceed but what if we have DEPENDENCY on result of the method/function which we invoked through XMLHTTPRequest object and suppose to proceed only when we get result and on the base of that result, we have to code further like:

Suppose i need to make functionality of SIGNIN  means Authenticate User. User enter his/her username and password and press Sign In and on SignIn we call javascript function which call server side function through XMLHTTPRequest object and that server side function check either user exist in DB or not if Yes then return True if no then return False and return that result back to client side and if True then redirect to WelcomePage if False then take to Error Page. Here you can see until we don't get result (either True or False).

so the solution is following code/snippet which you need to have along your code :)

<script type="text/javascript">
    var __xmlHttpRequest = window.XMLHttpRequest;
    window.XMLHttpRequest = XMLHttpRequest = function() {
        var _xmlHttp = null;
        if (!__xmlHttpRequest) {
            try {
                _xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
            }
            catch(ex) {}
        }
        else {
            _xmlHttp = new __xmlHttpRequest();
        }
       
        if (!_xmlHttp) return null;
        
        this.abort = function() {return _xmlHttp.abort();}
        this.getAllResponseHeaders = function() {return _xmlHttp.getAllResponseHeaders();}
        this.getResponseHeader = function(header) {return _xmlHttp.getResponseHeader(header);}
        this.open = function(method, url, async, user, password) {
            return _xmlHttp.open(method, url, false, user, password);
        }
        this.send = function(body) {
            _xmlHttp.send(body);
            this.readyState = _xmlHttp.readyState;
            this.responseBody = _xmlHttp.responseBody;
            this.responseStream = _xmlHttp.responseStream;
            this.responseText = _xmlHttp.responseText;
            this.onreadystatechange();
        }
        this.setRequestHeader = function(name, value) {return _xmlHttp.setRequestHeader(name, value);}
    }
</script>

 

It will work either you are using XMLHTTPRequest or AJAX or even ASP.NET CALLBACK butttttttttt in case of ASP.NET CALLBACK you can avoid that snippet,  when you register/embed client side method signature in "GetCallbackEventReference"

String cbReference = scriptMgr.GetCallbackEventReference(this"arg", "ReceiveServerData", "", TRUE|FALSE);
TRUE for Async and FALSE for Sync communication. 
ref: http://aspalliance.com/1573_Working_with_Callback_and_Control_Rendering.all listing 3

 

'__pendingCallbacks[...].async' is null or not an object: callback async[i]...FIX :)

In my prior both articles about CALLBACK, which considered as Article of the Day @ www.asp.net recently might have problem:

Here i would like to talk about async indexer problem and of course solution as well :)

PROBLEM 1: '__pendingCallbacks[...].async' is null or not an object

EXPLANATION: if you debug then error message says, there is some problem with indexer [i] of async callback, hmmm you might not get that error message after using callback but developing other modules/part of the website you might get such error 1 day as i did :D, so if you are brainy enough, you must think something new i did which cause this ripple effect and go ahead to look for that what exactly i did and if you keep thinking with reading that error message carefully, you will get to know: somewhere you are using "i" variable and that variable is not being getting out of scope so mixing with "i" variable of callback async[i] and making problem.

Solutions:
1) solution is simple: follow standards and never make any variable name of single character rather use: anyhow either change your variable name from "i" to intCounter or anything u want

2) take care of your variable scope, so it wont mixup with variable "i"

3) use the following code/snippet: if you want to keep using your "i" variable in your code (may be you have used that at many places and don't wanna mess up with your existing code):

<script type="text/javascript">
function WebForm_CallbackComplete

_SyncFixed() {
  // SyncFix: the original version uses "i" as global thereby resulting in javascript errors when "i" is used elsewhere in consuming pages
  for (var i = 0; i < __pendingCallbacks.length; i++) {
   callbackObject = __pendingCallbacks[ i ];
  if (callbackObject && callbackObject.xmlRequest && (callbackObject.xmlRequest.readyState == 4)) {
   // the callback should be executed after releasing all resources
   // associated with this request.
   // Originally if the callback gets executed here and the callback
   // routine makes another ASP.NET ajax request then the pending slots and
   // pending callbacks array gets messed up since the slot is not released
   // before the next ASP.NET request comes.
   // FIX: This statement has been moved below
   // WebForm_ExecuteCallback(callbackObject);
   if (!__pendingCallbacks[ i ].async) {
     __synchronousCallBackIndex = -1;
   }
   __pendingCallbacks[i] = null;

   var callbackFrameID = "__CALLBACKFRAME" + i;
   var xmlRequestFrame = document.getElementById(callbackFrameID);
   if (xmlRequestFrame) {
     xmlRequestFrame.parentNode.removeChild(xmlRequestFrame);
   }

   // SyncFix: the following statement has been moved down from above;
   WebForm_ExecuteCallback(callbackObject);
  }
 }
}
window.onload = function Onloaad(){
if (typeof (WebForm_CallbackComplete) == "function") {
  // set the original version with fixed version
  WebForm_CallbackComplete = WebForm_CallbackComplete_SyncFixed;
}
}
</script>

 

More Posts