Some user action trigger asynchronous server-side operations. The user can then be forced to check for results periodically by polling the server. Loadrunner 11.5 provides asynchronous logic allowing callback functions to be specified which are called when the async call finally returns. The following example gives one example of using the asynchronous callbacks as follows:
- Include web_api.h to load some needed symbols
- To capture the time it takes for the async response to come back, specify a global variable showing done state
- Before the async call, set async polling properties using web_reg_async_attributes such as how often to poll, which callback functions to use, etc.
- Define the callback functions to be called when the async response is returned and update the done state variable in the callback
- Make the async call
- To get the response time, wait until the callback has updated the global state variable
- End the transaction
- Stop the async polling
The following shows an example of a script doing this, and the next section shows the script's vugen console output.
Script
// Specify include files
#ifndef _GLOBALS_H
#define _GLOBALS_H
#include "web_api.h"
#endif // _GLOBALS_H
// End include files
// Define a global variable holding done state
int done;
Action()
{
web_url("wiki",
"URL=http://ajaxify.com/run/wiki",
"Resource=0",
"RecContentType=text/html",
"Referer=",
"Snapshot=t37.inf",
"Mode=HTML",
LAST);
// Initialize the global done state variable, and start the async transaction variable
done = 0;
#ifndef _GLOBALS_H
#define _GLOBALS_H
#include "web_api.h"
#endif // _GLOBALS_H
// End include files
// Define a global variable holding done state
int done;
Action()
{
web_url("wiki",
"URL=http://ajaxify.com/run/wiki",
"Resource=0",
"RecContentType=text/html",
"Referer=",
"Snapshot=t37.inf",
"Mode=HTML",
LAST);
// Initialize the global done state variable, and start the async transaction variable
done = 0;
lr_start_transaction("async-call");
// Define the request to be handled asynchronously, in this case a "?messages" call
// Define the request to be handled asynchronously, in this case a "?messages" call
// Specify the polling interval of 5 seconds
// Specify the callback functions that will be called when the response is returned.
// The callback functions are defined below.
web_reg_async_attributes("ID=Poll_0",
"URL=http://ajaxify.com/run/wiki/content.php?messages",
"Pattern=Poll",
"PollIntervalMs=5000",
"RequestCB=Poll_0_RequestCB",
"ResponseBodyBufferCB=Poll_0_ResponseBodyBufferCB",
"ResponseCB=Poll_0_ResponseCB",
LAST);
// now make the async call.
"URL=http://ajaxify.com/run/wiki/content.php?messages",
"Pattern=Poll",
"PollIntervalMs=5000",
"RequestCB=Poll_0_RequestCB",
"ResponseBodyBufferCB=Poll_0_ResponseBodyBufferCB",
"ResponseCB=Poll_0_ResponseCB",
LAST);
// now make the async call.
// note that the script will not block on this call. processing will continue on past this step while the request is handles asynchronously
web_url("content.php",
"URL=http://ajaxify.com/run/wiki/content.php?messages",
"Resource=0",
"RecContentType=text/xml",
"Referer=http://{host_ajaxify_com}/run/wiki/",
"Snapshot=t38.inf",
"Mode=HTML",
LAST);
// To capture the response time of the async call, wait until the callback is called.
web_url("content.php",
"URL=http://ajaxify.com/run/wiki/content.php?messages",
"Resource=0",
"RecContentType=text/xml",
"Referer=http://{host_ajaxify_com}/run/wiki/",
"Snapshot=t38.inf",
"Mode=HTML",
LAST);
// To capture the response time of the async call, wait until the callback is called.
// Without this, the script would move past and complete the iteration before the callback is called.
while (done==0)
{
lr_think_time(1);
}
// once the callback has been called, end the transaction to get the response time. lr_end_transaction("async-call", LR_AUTO);
{
lr_think_time(1);
}
// once the callback has been called, end the transaction to get the response time. lr_end_transaction("async-call", LR_AUTO);
// stop the polling
web_stop_async("ID=Poll_0",
LAST);
return 0;
}
/*
* Callback Implementation
*
*
*/
int Poll_0_RequestCB()
{
//enter your implementation for RequestCB() here
return WEB_ASYNC_CB_RC_OK;
}
int Poll_0_ResponseBodyBufferCB(
const char * aLastBufferStr,
int aLastBufferLen,
const char * aAccumulatedStr,
int aHttpStatusCode)
{
//enter your implementation for ResponseBodyBufferCB() here
// when the response is received, update the global variable
done = 1;
web_stop_async("ID=Poll_0",
LAST);
return 0;
}
/*
* Callback Implementation
*
*
*/
int Poll_0_RequestCB()
{
//enter your implementation for RequestCB() here
return WEB_ASYNC_CB_RC_OK;
}
int Poll_0_ResponseBodyBufferCB(
const char * aLastBufferStr,
int aLastBufferLen,
const char * aAccumulatedStr,
int aHttpStatusCode)
{
//enter your implementation for ResponseBodyBufferCB() here
// when the response is received, update the global variable
done = 1;
// print out the response body and length
lr_message("in Poll_0_ResponseBodyBufferCB response body callback");
lr_message("in Poll_0_ResponseBodyBufferCB response body callback, lastBufferLen=%d", aLastBufferLen);
return WEB_ASYNC_CB_RC_OK;
}
int Poll_0_ResponseCB(
const char * aResponseHeadersStr,
int aResponseHeadersLen,
const char * aResponseBodyStr,
int aResponseBodyLen,
int aHttpStatusCode)
{
//enter your implementation for ResponseCB() here
lr_message("in Poll_0_ResponseCB response callback, headerLen=%d, bodyLen=%d", aResponseHeadersLen, aResponseBodyLen);
lr_message("in Poll_0_ResponseCB response callback, header=%s", aResponseHeadersStr);
lr_message("in Poll_0_ResponseCB response callback, body=%s", aResponseBodyStr);
return WEB_ASYNC_CB_RC_OK;
}
lr_message("in Poll_0_ResponseBodyBufferCB response body callback");
lr_message("in Poll_0_ResponseBodyBufferCB response body callback, lastBufferLen=%d", aLastBufferLen);
return WEB_ASYNC_CB_RC_OK;
}
int Poll_0_ResponseCB(
const char * aResponseHeadersStr,
int aResponseHeadersLen,
const char * aResponseBodyStr,
int aResponseBodyLen,
int aHttpStatusCode)
{
//enter your implementation for ResponseCB() here
lr_message("in Poll_0_ResponseCB response callback, headerLen=%d, bodyLen=%d", aResponseHeadersLen, aResponseBodyLen);
lr_message("in Poll_0_ResponseCB response callback, header=%s", aResponseHeadersStr);
lr_message("in Poll_0_ResponseCB response callback, body=%s", aResponseBodyStr);
return WEB_ASYNC_CB_RC_OK;
}
Console Output
Running Vuser...
Starting
iteration 1.
Notify: max
connections per server : 6
Starting action
Action.
Action.c(16):
web_url("wiki") started [MsgId: MMSG-26355]
Action.c(16):
Redirecting "http://ajaxify.com/run/wiki" (redirection depth is
0) [MsgId:
MMSG-26694]
Action.c(16): To
location "http://ajaxify.com/run/wiki/" [MsgId:
MMSG-26693]
Action.c(16):
Found resource "http://ajaxify.com/run/Lib/css/demo.css" in HTML
"http://ajaxify.com/run/wiki/"
[MsgId: MMSG-26659]
Action.c(16):
Found resource "http://ajaxify.com/run/wiki/wiki.css" in HTML
"http://ajaxify.com/run/wiki/"
[MsgId: MMSG-26659]
Action.c(16):
Found resource "http://ajaxify.com/run/Lib/js/util.js" in HTML
"http://ajaxify.com/run/wiki/"
[MsgId: MMSG-26659]
Action.c(16):
Found resource "http://ajaxify.com/run/Lib/js/ajaxCaller.js" in HTML
"http://ajaxify.com/run/wiki/"
[MsgId: MMSG-26659]
Action.c(16):
Found resource "http://ajaxify.com/run/wiki/wiki.js" in HTML
"http://ajaxify.com/run/wiki/"
[MsgId: MMSG-26659]
Action.c(16):
Found resource "http://ajaxify.com/favicon.ico" in HTML
"http://ajaxify.com/run/wiki/"
[MsgId: MMSG-26659]
Action.c(16):
Found resource "http://ajaxify.com/run/Lib/php/button.php" in HTML
"http://ajaxify.com/run/wiki/"
[MsgId: MMSG-26659]
Action.c(16):
web_url("wiki") was successful, 22491 body bytes, 2152 header bytes,
24 chunking overhead bytes [MsgId: MMSG-26385]
Action.c(26):
Notify: Transaction "polling" started.
Action.c(41):
web_reg_async_attributes started [MsgId: MMSG-26355]
Action.c(41):
web_reg_async_attributes was successful [MsgId: MMSG-26392]
Action.c(50):
web_url("content.php") started
[MsgId: MMSG-26355]
Action.c(50):
"ID=poll_0" && "Pattern=Poll" &&
"PollIntervalMs=5000" now applied to
URL="http://ajaxify.com/run/wiki/content.php?messages" (RelFrameId=1,
Internal ID=10) [MsgId: MMSG-35172]
Action.c(50):
Retaining cross-step download of URL="http://ajaxify.com/run/wiki/content.php?messages"
(RelFrameId=1, Internal ID=10) [MsgId: MMSG-27658]
Action.c(50):
web_url("content.php") was successful, 0 body bytes, 0 header
bytes [MsgId:
MMSG-26386]
Action.c(62):
lr_think_time: 1.00 seconds.
in Poll_0_ResponseBodyBufferCB
response body callback
in
Poll_0_ResponseBodyBufferCB response body callback, lastBufferLen=928
in
Poll_0_ResponseBodyBufferCB response body callback
in
Poll_0_ResponseBodyBufferCB response body callback, lastBufferLen=0
in Poll_0_ResponseCB
response callback, headerLen=319, bodyLen=928
in
Poll_0_ResponseCB response callback, header=HTTP/1.1 200 OK
Server:
nginx/0.8.53
Date: Thu, 01 Nov
2012 21:18:42 GMT
Content-Type:
text/xml
Transfer-Encoding:
chunked
Connection:
keep-alive
X-Powered-By:
PHP/5.3.5-1ubuntu7.11
Expires: 0
Last-Modified:
Thu, 01 Nov 2012 21:18:42 GMT
cache-control:
no-store, no-cache, must-revalidate
Pragma: no-cache
in
Poll_0_ResponseCB response callback, body=<messages> <message>
<id>10</id>
<lastAuthor>lastAuthor</lastAuthor>
<ranking>100</ranking>
<content>Wonder%20Wonder%20ffff%0AStuff%20here%20for%20123fdsfd%0Atest%0Avbnvytytry%0Aokadfasdf%0Artyry%0Artyryry%0Arytry%0Adfgvdfg%0A%0Asdfsad%0A%0Asdfsd%0A%0Aghghhgggh%0A%0Atesteste%0A%0AZe%20woiauha%0A%20df%0A%0Axcvx%0AHello%20friends%21%0Ahello%20folks%0Ahi%0Ajiadsasd%0A%0A%0Azzz</content>
</message> <message>
<id>2</id>
<lastAuthor>lastAuthor</lastAuthor>
<ranking>200</ranking>
<content>ABC%0Aklljljl%0Ak%3Bk%3B%3Bk%3B%0Aggugj%0A%0Affff%0A%0Aasdf%0A%0Abla%0Aqwe%0Aqweqwe%0Ajnknknkjkvfgh%0A</content>
</message> <message>
<id>3</id>
<lastAuthor>lastAuthor</lastAuthor>
<ranking>300</ranking>
<content>This%20is%20line%201%0AThis%20is%20line%202.%0AEnd%0A.%0Adffdfg123123123%0Aawgaw%0Afsdf%0Atestes%0Aasdfadf%0Aadsasd</content>
</message></messages>
Action.c(62):
Issuing a "POLL" request for conversation with ID="poll_0"
and "PollIntervalMs=5000". Scheduling due at t=13494, URL="http://ajaxify.com/run/wiki/content.php?messages" [MsgId:
MMSG-35169]
Action.c(62):
"ID=poll_0" && "Pattern=Poll" &&
"PollIntervalMs=5000" now applied to
URL="http://ajaxify.com/run/wiki/content.php?messages" (RelFrameId=,
Internal ID=11) [MsgId: MMSG-35172]
Action.c(67):
Notify: Transaction "polling" ended with "Pass" status
(Duration: 4.0431 Think Time: 1.8491 Wasted Time: 0.0121).
Action.c(69):
web_stop_async started [MsgId: MMSG-26355]
Action.c(69):
Notify: Deleting Conversation Information with ID="poll_0"
Action.c(69):
Aborting download of URL
"http://ajaxify.com/run/wiki/content.php?messages" (RelFrameId=,
Internal ID=11) of conversation with ID="poll_0" [MsgId:
MMSG-35167]
in
Poll_0_ResponseBodyBufferCB response body callback
in
Poll_0_ResponseBodyBufferCB response body callback, lastBufferLen=0
in
Poll_0_ResponseCB response callback, headerLen=0, bodyLen=0
in
Poll_0_ResponseCB response callback, header=
in
Poll_0_ResponseCB response callback, body=
Action.c(69):
web_stop_async was successful [MsgId: MMSG-26392]
Ending action
Action.
Ending iteration
1.
Ending Vuser...
Starting action
vuser_end.
Ending action
vuser_end.
Vuser Terminated.
No comments:
Post a Comment