Questions on Websocket Replay with Web HTTP/HTML protocol

  • KM00972510
  • 04-Jun-2014
  • 04-Jun-2014

This document is under revision.

Summary

This article is about questions on Websocket replay -- regarding how it work, how transaction response times are measured etc..

Question

Questions on WebSocket Replay with Web HTTP/HTML protocol

Answer

FAQ on Websocket Recording and Replay:


1) What is happening in the WebSocketRecieve in  WebSocketBuffer.h?  Action.c has only send and not receive.   When or under what condition(s) is(are) received buffers used?

Answer :

The receive buffers  are saved in WebSocketBuffer.h for information only.   Iin the action.c you can see comment notifying “when” a buffer was received.

2) In the replay log  (output.txt)  we are seeing the following --

Action.c(78): t=5289ms: 717-byte response body for "ws://mstlva-dsnecm05.csc.nycnet/smart-opsboard-0.4.0-SNAPSHOT/hello/BKN03/20140522/357/ak5zgbdj/websocket" (RelFrameId=1, Internal ID=55)   [issued at Action.c(168)]
Action.c(168):     \x81~\x00\x89a["CONNECTED\\nuser-name:1\\nheart-beat:10000,10000\\nsession:session-5Repd8s
Action.c(168):     QynKtXvGybkCbjg\\nserver:RabbitMQ/3.3.0\\nversion:1.1\\n\\n\\u0000"]\x81~\x02<a["MESSAGE\\

There are hex characters. Is there a way to convert this to ASCII readable format ?


3) When server receives a message we see onopenCB0. If a breakpoint is put and if user hits enter after 30 seconds, then the connection is lost.  What is happening and why is the session lost after 8 or 9 min.   What timeout comes into effect?

Here is the replay log when the breakpoint is put in it –

Action.c(206): t=79294ms: Request done "ws://mstlva-dsnecm05.csc.nycnet/smart-opsboard-0.4.0-SNAPSHOT/hello/BKN03/20140522/357/ak5zgbdj/websocket"   [MsgId: MMSG-26000]
Action.c(206): t=79298ms: Inactive socket [4] was closed by mstlva-dsnecm05.csc.nycnet:80, probably due to Keep-Alive timeout   [MsgId: MMSG-26000]
Action.c(206): t=79298ms: Closed connection [4] to mstlva-dsnecm05.csc.nycnet:80 after completing 3 requests   [MsgId: MMSG-26000]
Action.c(206): t=79298ms: Inactive socket [5] was closed by mstlva-dsnecm05.csc.nycnet:80, probably due to Keep-Alive timeout   [MsgId: MMSG-26000]
Action.c(206): t=79298ms: Closed connection [5] to mstlva-dsnecm05.csc.nycnet:80 after completing 2 requests   [MsgId: MMSG-26000]
Action.c(206): t=79793ms: Inactive socket [0] was closed by mstlva-dsnecm05.csc.nycnet:80, probably due to Keep-Alive timeout   [MsgId: MMSG-26000]
Action.c(206): t=79794ms: Closed connection [0] to mstlva-dsnecm05.csc.nycnet:80 after completing 23 requests   [MsgId: MMSG-26000]
Action.c(206): t=79794ms: Inactive socket [1] was closed by mstlva-dsnecm05.csc.nycnet:80, probably due to Keep-Alive timeout
[MsgId: MMSG-26000]
Action.c(206): t=79794ms: Closed connection [1] to mstlva-dsnecm05.csc.nycnet:80 after completing 17 requests   [MsgId: MMSG-26000]
Action.c(206): t=79794ms: Inactive socket [6] was closed by mstlva-dsnecm05.csc.nycnet:80, probably due to Keep-Alive timeout   [MsgId: MMSG-26000]
Action.c(206): t=79794ms: Closed connection [6] to mstlva-dsnecm05.csc.nycnet:80 after completing 1 request   [MsgId: MMSG-26000]

Abort was called from an action.

Answer:

The \81~\x00 are part of the WebSocket header (http://tools.ietf.org/html/rfc6455#section-5.2) you can comment out the example code in the OnMessage callback and print the data without the header.


3) In the replay log  (output.txt)  we are seeing the following --

Action.c(78): t=5289ms: 717-byte response body for "ws://mstlva-dsnecm05.csc.nycnet/smart-opsboard-0.4.0-SNAPSHOT/hello/BKN03/20140522/357/ak5zgbdj/websocket" (RelFrameId=1, Internal ID=55)   [issued at Action.c(168)]
Action.c(168):     \x81~\x00\x89a["CONNECTED\\nuser-name:1\\nheart-beat:10000,10000\\nsession:session-5Repd8s
Action.c(168):     QynKtXvGybkCbjg\\nserver:RabbitMQ/3.3.0\\nversion:1.1\\n\\n\\u0000"]\x81~\x02<a["MESSAGE\\

There are hex characters. Is there a way to convert this to ASCII readable format ?


Answer :  For websocket connection, if you put a breakpoint in OnOpenCB, if the server does not receive any feedback from the client after a certain period of time, the server will close the connection. The timeout is defined by the server side.
You mentioned that the session will lost after 8~9 min, this is more complicated, the user (scripter) needs to check the real reason on server side. The user(scripter) may add some more logic in OnMessageCB to make sure the server side get the desired information.
 
--------

4) How is transaction response time measure in websocket application replay ?

Answer : 

It is the time between message being sent by client and the client getting the message from the server.   If so, the general idea is to start the transaction after the web_websocket_send and stop the transaction in the OnMessageCB.

The logic of the script  is to start a connection, then the server will sent message to client time to time, each time when the client get the message, it will start a request to get images from the server.

After 10 times, the websocket connection will close.


5) How is websocket heartbeat session maintained by LoadRunner?

 As per the documentation PING/PONG was handled automatically by replay engine.

    However,  if I have a think time more than 30 sec's  I get Warning "-35047: The WebSocket with ID = "0" is not connected" message..How to handle this situation?

    If some transaction takes more than 30 seconds, will websocket connection get closed ?
   
    In browser it keep on sending ping pong message continuously. Please explain how to handle this situation.


Answer :  Yes, the normal websocket ping/pong is handled by loadrunner.

However,  some websocket implementation will use its own heartbeat “ping/pong”, for instance the socketio will use a text message for heartbeat like “2::”, because socketio wanst to support some browser that does not really support websocket.

If this is the case,  then you  just need to implement the heartbeat in the OnMessageCB.

Please refer to the websocketio_monitor OnMessageCB0.

Sometimes,  the websocket implementation that you are  using may have some special text message as ping/pong just like websocketio.

For exampel, your ping may be  like a[\"\\n\"]  and pong  [\"\\n\"].

So you  will need to send the pong [\"\\n\"] back to the server in the OnMessageCB, once it received a ping, a text message a[\"\\n\"]  .    You  need a similar logic as specified in websocketio_monitor.

Below is a sample for the OnMessageCB.

void OnMessageCB0 (const char* connectionID,
                  int isbinary,
                  const char * data,
                  int length)
{
    int isheartbeat;
    isheartbeat = strncmp(data,"a[\"\\n\"]", 7);

    if(isheartbeat==0) {
        web_websocket_send("ID=0","Buffer=[\"\\n\"]","IsBinary=false",LAST);
    }
}


Note: LoadRunner will automatically handle ping/pong frame of websocket, please refer to http://tools.ietf.org/html/rfc6455#section-5.2. For the specific implementation that uses special text message as ping/pong, you will have to handle those message by yourself.

6) You said that for some reason, you are seeing issues when you run the script in Vugen  (for single user).  The Script is not failing all the times,  but you are seeing issues with few iterations.

You noticed these issues with only LoadRunner.  Manual testers never noticed this issue (even you never noticed this issue manually).

Failed Reasons:


c[1002,"null"]

a["ERROR\nmessage:Connection to broker closed\ncontent-length:0\n\n\u0000"]

Warning -35047: The WebSocket with ID = "0" is not connected


   But even on standard websocket return code failures (like 1002), the  script never called onErrorCB0/OncloseCB0 instead of called OnmessageCB0.

Even when  you get message like "Warning -35047: The WebSocket with ID = "0" is not connected" & "Error -27790: Failed to transmit data to network: [10038] Socket operation on non-socket"

The script never stopped replaying.


So you thought of adding the following logic in OnCloseCB0 to stop VUser on all failures codes and report failure. But even for c[1002,"null"] it is getting return code as 1000.

To begin with 1002 (return code)  never went to on ErrorMessageCB0/OncloseCB0.

OnCloseCB0
if(code=1000)
                {
                                lr_output_message("Happy close WebSocket ID = %s closed. CloseCode= %d, CloseReason=%s", connectionID, code, reason);
                }

                else
                {                              {
                                lr_output_message("WebSocket ID = %s closed. CloseCode= %d, CloseReason=%s", connectionID, code, reason);
                                 lr_exit(LR_EXIT_VUSER, LR_FAIL);
                }

Questions :

(1) You noticed these errors and you are not sure how many other types of errors you will get in other runs.  However, all of them went onMessageCB0.

Onclose you are getting returncode1000, you would really like to differentiate Failures with Successful replay.  How can you do this?

(2) You want the script to exit the user when there is a failure.

You want to know if you can add vuser exit logic on Onclose getting returncode1000 ?

(3) If you do that, will LoadRunner gracefully exit the connections ?

 

Answers from R&D :

It looks like the customer got failures on some cases, but he got the errors from OnMessage, right? I saw the script that the user didn’t use OnMessage to send back the pong message. I think that may cause issues since it’s may be not the “correct” message the server is expecting.

Below is my answers for the questions:
(1)    He noticed these errors and is not sure how many other types of errors he will get in other runs.  However, all of them went onMessageCB0.

Onclose he is getting returncode1000, he would really like to differentiate Failures with Successful replay.  How can he do this?

            WebSocket is very flexible on how to use it. Different implementation may use OnMessage instead of OnError to show errors. That means not every error has to go to OnError, that depends on the implementation.
                In this case the customer can write if…else… in OnMessage to judge if the errors occurs, and call exit vuser in the OnMessageCB.

(2)    He wants the script to exit the user when there is a failure.

He wants to know if he can add vuser exit logic on Onclose getting returncode1000 ?
            Yes, I think he can add such logic.

(3)    If he does that, will LoadRunner gracefully exit the connections ?
Yes, LoadRunner will exit the connection gracefully. If you have any issue, please let us know.