LoadRunner and Performance Center
Showing results for 
Search instead for 
Do you mean 

Async. Communications: The WebSocket protocol made easy in LoadRunner 12.00

Anonymous_User1 ‎05-15-2014 10:00 AM - edited ‎09-22-2015 01:46 PM

(This post was written by Peng-Ji Yin (Jerry), with contributions from Avishai Moshka, both from the LoadRunner R&D Team)


HTML5 introduced several features for web developers. One of the major features is WebSocket, which is a full-duplex asynchronous communication channel over a single TCP connection. The channel can be used for continuous communication between the client and the server. See my colleague Wilson Mar's post for a brief introduction to the concept.


Before LoadRunner 12.00, it was almost impossible to record/replay WebSocket traffic. I say ’almost’, because some of our customers did manage to use the Windows Sockets protocol to handle WebSocket connections. But it took them enormous effort, maybe several months of work, to prepare a workable script. The good news is that LoadRunner 12.00 makes their life much easier! This post will take a look at the new support for WebsSockets, which is actually an enhancement to the Web-HTTP/HTML protocol for supporting HTML5 features, rather than a new protocol.



Recording doesn’t require any special treatment. Just record a Web-HTTP/HTML script as usual, and if there are WebSocket connections, they will be recorded. Here’s a screenshot of a project and script after it’s been recorded: 


Notice that two new files, “WebSocketBuffer.h” and “WebSocketCB.c”, have been added to the project, and there are some new API functions whose names start with “web_websocket”.


All buffers received by the client will be stored in WebSocketBuffer.h.  Buffers larger than 1024 characters sent by the client are stored in WebSocketBuffer.h, while smaller buffers are contained in the web_websocket_send ‘Buffer’ argument: 


The callback functions -  OnOpen, OnMessage, OnClose and OnError -will be generated automatically in WebSocketCB.c, along with the commented out sample code:



Before replay, let’s look at the three new APIs that were introduced for WebSockets.


Connection API

web_websocket_connect("ID=0", "URI=ws://your_server:port/",
                          "OnCloseCB=OnCloseCB0", LAST);

The important arguments are ID, URI and the four callbacks. You can find the meaning of other arguments from the online help.

  • ID: A unique number indicating the connection index. This value is generated automatically during the code generation.
  • URI: The endpoint WebSocket with which to connect.  Note that bothws (WebSocket) and wss (WebSocket Secure) are supported.
  • OnXxxCB: The callbacks will be registered for the connection. Different WebSocket connections may share the same callbacks. For example, if you open a new connection whose ID is “1”, you can re-use the OnOpenCB0 for this connection, even though it may have already been registered for the connection “0”. 


In simple cases where there is no client logic, the callbacks can be used for logging or for setting user datapoints. If the application contains a lot of client logic, the callbacks are the place where you implement that logic in the script. For example, if the client needs to give feedback when it gets a message from the server, it can be done in the OnMessage callbacks. APIs such as web_url and web_websocket_send will work in the callbacks.


Here is a sample OnMessage callback. Since the application uses WebSocket.IO, which uses its own heartbeat messages, the callback will send back a heartbeat when it receives one from the server. Besides the heartbeat, the function also gets the required information and saves it to a parameter:


void OnMessageCB0 (
const char* connectionID,
		int isbinary,
		const char * data,
		int length)
	int isactivesession;
	int isheartbeat;
	int isupdate;

	lr_output_message("WebSocket ID = %s got message=%s length = %d, ", connectionID, data, length);

	isactivesession = strncmp(data,"5:::{\"name\":\"message\"",21);
	isupdate = strncmp(data,"5:::{\"name\":\"update\"",20);
	isheartbeat = strncmp(data,"2::",3);

	if(isheartbeat==0) {
		lr_user_data_point("Heartbeat message",1);
		lr_output_message("WebSocket ID = %s heartbeat message sent back", connectionID);

	if(isactivesession==0) {
		lr_save_param_regexp (
			LAST );

lr_user_data_point_ex("Active Sessions", atoi(lr_eval_string("{myActiveSessions}"))-1, DP_FLAGS_EXTENDED_LOG);
		lr_output_message(">>>> got visits counter!!!");

	if(isupdate==0) {
		lr_save_param_regexp (
			LAST );

		lr_user_data_point_ex("LoadRunner price", atof(lr_eval_string("{myLRPrice}")), DP_FLAGS_EXTENDED_LOG);
		lr_output_message(">>>> got price update!!!");

	if (counter++ > 10) lr_save_string("OK","ready");



Send API


web_websocket_send("ID=0", "Buffer=abcde", "IsBinary=0", LAST);
web_websocket_send("ID=0", "Buffer=abcde", "IsBinary=1", LAST) ;
web_websocket_send("ID=0", "Buffer/Bin=\x61\x62\x63\x64\x65", "IsBinary=0", LAST)


The arguments are as follows:

  • Buffer: The text that will be sent.
  • Buffer/Bin: Use this to send a message in binary mode.  The buffer may contain zeros.
  • IsBinary: Indicates whether the data will be sent in text or binary mode. In non-binary mode, ie. when IsBinary is set to 0, the message will be truncated at the first zero. In binary mode, all content in the buffer will be sent.

If you need to send long messages or big buffers/files, it’s better to store it in a parameter, which makes the script code cleaner and more maintainable.  For example, this code will save a big string to a parameter WebSocketSend0 which will be sent later:

char* BigString = “….”;
lr_save_string(BigString, "WebSocketSend0");
web_websocket_send("ID=0", "Buffer={WebSocketSend0}", "IsBinary=0", LAST); 


Close API

web_websocket_close("ID=0", "Code=1000", "Reason=Any Reason...", LAST);


The Code and Reason arguments can be omitted for this API. If the Code argument is supplied, the value must be an integer between 1000 and 1011, with the default value being 1000 [RFC6455 Section-7.4]. If Reason is not specified, the default value will be empty.



After adding the necessary client-side logic to the script, just click the replay button or press F5 to replay the script. Don’t forget to turn on the extended log in the Run-Time Settings dialog when debugging the script. Since there are no snapshots for the WebSocket steps, logs are vital. All of the handshake information, as well as sent/received messages, will be shown in the extended log.


During replay, some WebSocket-related datapoints will be generated. The WebSocket Statistics graph in the Controller shows the number of new or closed connections, the number of bytes sent, and the number of bytes received:





Here are some tips for creating a script.

  • Add think time in the script to allow callbacks to be invoked
  • You can assign the same callback to different connections
  • Callbacks are allowed to invoke Web actions
  • Use WireShark with the “WebSocket” filter to verify or monitor WebSocket traffic
  • For large binary buffers (file uploads), load the file to a parameter


Is there an option to run the WebSocket script synchronously, so that it waits for the previous step to be completed (including reply from the server) before performing the next one?

The web_websocket_connect, web_websocket_send and web_websocket_close are all synchronized APIs, and will be executed one-by-one. While the WebSocket can receive the data from the server at any time, this is done asynchronously by design.

You can also use the web_sync API.


I don’t see WebSocket steps in my script!

  1. Don’t panic!
  2. Verify with WireShark that the AUT actually has WebSocket traffic. When recording in a browser, you can  verify it using the developer tools (by pressing F12 for IE, Chrome and Firefox).
  3. Verify that the full handshake appears in the code generation log
    1. Search for the 101 response from the server and verify that Upgrade: WebSocket and Connection: Upgrade headers are valid
    2. Validate that the handshake headers are compliant with RFC6455
  4. Verify in the recorded events log that WebSocket events exist by searching for websocket_snd and websocket_rcv events
  5. Still nothing? Check that the WebSocket Analyzer is loaded during recording, by looking for the following information in the recording log:

[Network Analyzer ( 6b8: 508)]     Analyzer Module: QTWeb (value=GetWebSocketProtocolAnalyzer:WebSocketAnalyzer.dll)

[Network Analyzer ( 6b8: 508)]     + Network Analyzer: WebSocketAnalyzer.dll @ GetWebSocketProtocolAnalyzer Loaded!



Leave a comment in the comment box below to let us know if you found this article useful.


To download HP LoadRunner, click here


Thanks to Jerry and Avishai for providing this article!

About the Author


boba kim
on ‎06-24-2014 10:31 PM

is websocket support the mobile protocols as well?

on ‎12-03-2014 04:31 PM

How do you capture the response time of these async responses ? 

Mahesh Venkat
on ‎01-04-2015 10:39 AM

Do you support record and play of websocket traffic where the client is not a browser and it is standalone websocket client ?

The client could be a device too.


on ‎01-06-2015 05:30 AM
@boba kim, mobile protocol does not support websocket yet.
on ‎01-06-2015 05:33 AM

@Mahesh Venkat, The client has to be running on the same machine of VuGen. It's not supported if the client is on a mobile device.

on ‎07-22-2015 11:30 PM

 How to deal with websocket protocol script, if there are cookies and session values in the script ? Please help

Prasad KGVS
on ‎07-26-2016 02:54 AM

hi on our appliction we use two connections one for HTPS and another for Websoket for listening for server notifications. Can I user Loadrunner for loadtesting our application? 

on ‎09-16-2016 08:48 AM

Awesome article!!


27 Feb - 2 March 2017
Barcelona | Fira Gran Via
Mobile World Congress 2017
Hewlett Packard Enterprise at Mobile World Congress 2017, Barcelona | Fira Gran Via Location: Hall 3, Booth 3E11
Read more
Each Month in 2017
Software Expert Days - 2017
Join us online to talk directly with our Software experts during online Expert Days. Find information here about past, current, and upcoming Expert Da...
Read more
View all