Adobe Flex/AMF: Handling Polling and Streaming

This tutorial describes how to design a realistic virtual user containing Adobe Flex/AMF requests . It shows the modeling in NeoLoad of the two standard ways of refreshing data from the Flash client, notably polling and streaming (also called "push"). At the end of the tutorial, you will also find an example of advanced design, with details on how to extract and interpret data returned by a server via a streaming channel.

To gain the most from this tutorial, it is recommended to have read the "Adobe Flex/AMF: Handling External Libraries" tutorial beforehand.

Understanding the Context

NeoLoad allows the user to load test AMF requests. These requests are based on standard HTTP interactions. In most web applications, the request for data comes from the client (the web browser). In other words, it's the user who requests information either by clicking on a link or performing some other action. In some cases however, the server needs to send information to the client without the user requesting it. Typical examples of this are a server-initiated events such as alert messages and data updates.

Flex servers using the AMF protocol update client data in two ways:

  1. the polling method: This involves the browser querying the server at regular intervals. Technically simple in its implementation, the method's downside is that it needlessly overloads the server and it is not very reactive.

  2. the streaming, or "push" method: In this case, the client sends a single request to the server, and the server responds when pertinent information is available, without closing the request. Thus, the server can again send information to the client using the same connection, without having to wait for a new request. Using this method, client data can be rapidly updated while the network traffic is kept minimized.

The polling method uses a standard request/response structure. See the section called “Defining a Virtual User Using Polling-type AMF Requests”.

On the other hand, streaming requires the use of specific streaming-type requests in NeoLoad, which can handle the specific characteristics of this type of transaction. See the section called “Defining a Virtual User using Streaming-type AMF Requests”.

Defining a Virtual User Using Polling-type AMF Requests

We're going to use an example provided by Adobe and included in BlazeDS (http://opensource.adobe.com/wiki/display/blazeds/BlazeDS). Follow the installation instructions and then start the BlazeDS server. Then, go to the following URL: http://localhost:8400/samples/traderdesktop/startfeed.jsp. This page activates the stock price fluctuation simulation.

The following procedure details the steps involved in creating a Virtual User that uses AMF polling :

  1. Recording the scenario

  2. Defining the Virtual User

  3. Validating the Virtual User

  4. Viewing a load test that includes polling requests

  1. Recording the scenario

    1. Start recording

      In the NeoLoad main window, click the button in the toolbar. Enter UserPolling in the "Name" field.

    2. Access the application

      The web browser opens. Enter the following URL: http://localhost.:8400/samples/traderdesktop/index.html

    3. Note the polling operating mode

      The my-polling-amf mode is selected by default. This corresponds to an operating mode using polling requests. The average delay between these requests is 4 seconds. This means there will be a minimum 4 second delay between two updates of the "Watch List". Please wait twenty seconds or so (in other words, five refresh cycles).

    4. Stop the recording

      Close the browser. Click on "Finish" button.

    5. Check the recording

      Click on the virtual user node. Then, right click and select "Expand All". Each polling request appears in a separate page.

  2. Designing the Virtual User

    1. Remodel the polling requests

      Requests with pattern "POLL..." are called polling requests. Each polling request represents a call of the Flash client to get an update from the server.

      Delete all pages named "POLL..." except the first one. This will enable the number of polling requests sent to the server to be configured using NeoLoad thanks to a loop logical action.

    2. Add the polling requests to a loop

      Drag and drop the Loop logical action under the /samples/traderdesktop/index.html page. Then drag the POLL page into the loop logical action created previously. Finally, click loop and enter 15 in the "Execute loop" field. Each Virtual User will send 15 polling requests to the server.

  3. Validating the Virtual User

    1. Go to the Virtual User validation section

      In the NeoLoad main window, click the button in the toolbar.

    2. Configure the think time playback

      Click the "Advanced..." button in the validation window. Check the "Play thinktime" box, then click OK.

    3. Start the Virtual User validation

      Click the button in the validation window.

    4. Check the server responses

      Several polling requests have been executed. Click on one of these requests to check its content. After having selected a request, click "Response".

      The speed of execution in the validation playback is real; this avoids submitting the server to too high a polling rate. In testing, 4 seconds minimum separate each polling request.

      NeoLoad allows you to work on an XML representation of the objects passing through the server. In this example, we can see the XML representation of an instance of the example class flex.samples.marketdata.Stock returned by the server.

      <body class="ASObject" mappedClass="flex.samples.marketdata.Stock">
          <open tagClass="double">33.61</open>
          <last tagClass="double">32.41972272641574</last>
          <symbol tagClass="String">GE</symbol>
          <name tagClass="String">General Electric Company</name>
          ...
        </body>
      Here's an extract of the associated Java class:
      package flex.samples.marketdata;
      
      import java.util.Date;
      
      public class Stock {
          protected double open;
          protected double last;
          protected String symbol;
          protected String name;
          ...
      
          public double getOpen() {
              return open;
          }
          public void setOpen(double open) {
              this.open = open;
          }
      
          public double getLast() {
              return last;
          }
          public void setLast(double last) {
              this.last = last;
          }
      
          public String getSymbol() {
              return symbol;
          }
          public void setSymbol(String symbol) {
              this.symbol = symbol;
          }
      
          public String getName() {
              return name;
          }
          public void setName(String name) {
              this.name = name;
          }

  4. Viewing a load test that includes polling requests

    1. Go to the Population definition section

      In the NeoLoad main window, click on the

    2. Define the default Population

      In the Population Creation wizard, click "OK" .

    3. Go to the load policy section

      Click on the

    4. Define the load policy

      Enter 40 in the "Simulated users" field. NeoLoad will launch 40 Virtual Users using polling.

    5. Start the test

      Click the button in the toolbar. Then click "OK". The test starts. Wait 2 minutes.

    6. Results

      As the test proceeds, NeoLoad clearly displays the two sides of the application. First, the connection phase, which is the most resource-consuming, and second, the polling requests, which don't consume much but are very numerous.

Defining a Virtual User using Streaming-type AMF Requests

We'll use the same example as before, namely one provided by Adobe and included in BlazeDS (http://opensource.adobe.com/wiki/display/blazeds/BlazeDS). Follow the installation instructions and then start the BlazeDS server. Then, go to the following URL: http://localhost:8400/samples/traderdesktop/startfeed.jsp. This page activates the stock price fluctuation simulation.

The following procedure details the steps involved in creating a Virtual User that uses AMF streaming:

  1. Recording the scenario

  2. Defining the Virtual User

  3. Validating the Virtual User

  4. Viewing a load test that includes a streaming request.

  5. To learn more: Virtual User advanced definition

  1. Recording the scenario

    1. Start recording

      In the NeoLoad main window, click the button in the toolbar. Enter "UserStreaming" in the "Name" field and click on "OK".

    2. Access the application

      The web browser opens. Enter the following URL: http://localhost.:8400/samples/traderdesktop/index.html

    3. Change the operating mode to "streaming"

      The my-polling-amf operating mode is selected by default. Change the mode to my-streaming-amf in the list to apply the operating mode corresponding to streaming requests. The server refreshes the displayed data when it decides it is necessary. You can see the difference in refreshment rate compared with polling mode. Please wait ten seconds or so.

    4. Stop the recording

      Change back to the my-polling-amf mode in order to shut down the streaming. Then close the browser. Then click on "Finish".

    5. Check the recording

      Click on the node of the just created virtual user. Then, right click and select "Expand All". Two streaming requests are shown (indicated by the icon), named /samples/messagebroker/streamingamf open and /samples/messagebroker/streamingamf close: these are the opening and closing of the streaming.

      Click on the page right after SUBSCRIBE. Note the think time. This corresponds to the number of milliseconds during which streaming was used. NeoLoad detected this think time. In an advanced scenario, it's possible to make this think time dynamic, by creating a random variable whose limits correspond to the maximum and minimum think times.

    6. Check the "streaming open" request

      Unlike in polling mode, in this mode just one request is sent to the server. The server send data back in a response when it decides it's appropriate, until it closes the connection when streaming is finished. These different response data groups are stored by NeoLoad as several responses.

      Select the /samples/messagebroker/streamingamf open request. Click the "Advanced" button. In the dialog box, select the "Recorded response" tab. Finally, in the left-hand pane, select one of the responses. NeoLoad displays a list of all the responses sent by the server during the streaming request's recording.

  2. Defining the Virtual User

    1. Add a variable extractor

      Click on the "Variable extractors" tab, then click on "+".

    2. Define an extractor on the response, in order to detect end of streaming

      A new window opens. In the "Variable name" field, enter "AmfStreamClosed". In the "Starting with" pane, click on . In the left-hand section, scroll down and select the last response. Select <AMFCloseMessage> <closed>, then click on "Pick selected text". In the "Ending with" pane, click on . Select </closed>, then click on "Extract the selected text".

    3. Error handling

      During the streaming process, the server send several types of response. NeoLoad must be told that it's normal if no operation is found in the response.

      Click on the "Errors" tab. Clear the "Throw an assertion when no match found in page". Click OK to validate the extractor definition, then click "OK" again.

    4. Go to the Virtual User validation section

      In the NeoLoad main window, click the

    5. Add a second execution thread

      The streaming open request stays permanently active, that is to say it will only receive a response when the server decides to send an update. To handle this atypical HTTP behavior, a second execution thread needs to be created for this request. To do this, drag and drop the Fork logical action under the UNSUBSCRIBE page.

    6. Add a loop to play the server's various responses

      Once the streaming with the server is in place, the server's various updates (the responses in other words) will arrive each time the request is played. Therefore, a loop must be placed on the request so that each of the server's responses can be played, until the streaming is closed. When the server closes the streaming, the previously extracted variable ${AmfStreamClosed} will have a value of true.

      Drag and drop the While logical action in the fork logical action created previously. Double-click on the "Operand1" field, then click on and select "AmfStreamClosed". Click OK. In the "Operator" field, select "Doesn't equal to". In the "Operand2" field, enter "true". This will loop the streaming request until the server closes the socket, that is to say, the end of streaming.

      Finally, drag the page /samples/messagebroker/streamingamf open into the while logical action created previously.

  3. Validating the Virtual User

    1. Go to the Virtual User validation section

      In the NeoLoad main window, click the button in the toolbar.

    2. Configure the think time playback

      Click the button in the validation window. Check the "Play thinktime" box, then click OK..

    3. Start the Virtual User validation

      Select "UserStreaming" in the "Virtual Users" list. Then click the button in the validation window.

    4. Check the server responses

      The same streaming request appears several times. Only one request was issued for this Virtual User, but the server regularly sends back partial responses. When each partial response is received, a line is added to the list of played requests, together with its content. Click on one to check the contents. When the request is selected, click on "Response".

  4. Viewing a load test that includes a streaming request

    1. Go to the Population definition section

      In the NeoLoad main window, click on the

    2. Define the default Population

      In the Population Creation wizard, click OK.

    3. Go to the load policy section

      Click on the

    4. Define the load policy

      Enter 9 in the "Simulated users" field. NeoLoad will launch 9 Virtual Users using streaming (by default, the server will not allow more than 10 simultaneous streaming sessions).

    5. Start the test

      Click the button in the toolbar. Then click "OK". The test starts. Wait 2 minutes.

    6. Results

      As the test proceeds, NeoLoad clearly shows the speed of such an architecture, with a considerable number of responses being received by each Virtual User. Streaming also provides very fast response times. However, its use implies greater server-side resources than are required for polling and, therefore, a reduced capacity in handling simultaneous users.

  5. To learn more: Virtual User advanced definition

    We shall continue with the previous example, this time focusing on the content of the response to the streaming request. We shall see how NeoLoad extract part of the content sent by the server and help us to take decisions. Here is the proposed scenario: when the value of the General Electric (symbol GE) stock rises above 31, a log is displayed and the Virtual User stops.

    1. Go to the Virtual user profiles

      In the NeoLoad main window, click on the

    2. Add a variable extractor

      In the tree, select the first request, /samples/messagebroker/streamingamf open. Next, click the "Advanced" button. In the Advanced window, select the "Variable extractors" tab. Click on +.

    3. Select an XML node in the response

      In the "Variable name" field, enter "GE_last". Select the entry "XML node", then click onin the "XML Node" pane. In the "Filter" field, enter "GE". The tree will only display the items or sub-items whose value and/or attribute contains the string GE. Select the first XML node, named "body".

      This filter instructs NeoLoad to select the "body" node in the next server response, among all the responses returned by the server during recording.

      Click OK to validate the selected item.

    4. Filter only the nodes associated with the GE (General Electric Company) stock

      NeoLoad has generated an XML filter corresponding to all responses. In this tutorial, we want to extract the value of the GE stock. To do this, we need to filter the XML nodes containing the "symbol" sub-node with the value "GE". Replace this definition

      NeoLoadStreamResponses/<...>/body[1]
      with

      NeoLoadStreamResponses/<...>/body[symbol='GE']

      Caution: <...> must be relevant to your particular case.

      During the playback, the GE stock is not the only one updated. When the server sends back the updated IBM stock price for example, NeoLoad will flag an error. To prevent this happening, click on the "Errors" tab and enter "0" in the "Default value" field. Next, un-check the "Throw an assertion when no match found on page" box. Then go back to the "Definition" tab.

    5. Extract the "last" field from the selected node

      In the "Starting with" pane, click on . Select <last tagClass="double">, then click on "Pick selected text".

      In the "Ending with" pane, click on . Select </last>, then click on "Pick selected text".

    6. Validate the variable extractor

      Finally, check the result of the extraction. At the bottom of the variable extractor definition window, the contents of the "Value extracted from recorded page" field must be a number.

      Click "OK" to validate, then click "OK" again.

    7. Go to the Virtual User editing section

      In the NeoLoad main window, click on the

    8. Define a "GE_last > 31" conditions block

      Drag and drop the If...Then...Else logical action under the /samples/messagebroker/streamingamf open page. Double-click in the "Operand1" field. Then click on and select "GE_last". Click "OK". In the "Operator" field, select "is more than". In the "Operand2" field, enter "31". This conditions block will only be true where the General Electric stock price exceeds 31.

    9. Define the Virtual User actions where GE_last > 31

      Drag and drop the /samples/messagebroker/streamingamf close page in the Then block. This will instruct the server explicitly to close the streaming.

      Drag and drop the JavaScript logical action underneath. Delete the default code, and replace it with:

      // Get variable value from VariableManager
      var GE_last = context.variableManager.getValue("GE_last");
      if (GE_last == null) {
              context.fail("Variable 'GE_last' not found");
      }
      
      logger.debug("Buy GE at "+GE_last);
      Drag and drop the Stop Virtual User logical action underneath.

    10. Validate the Virtual User

      In the NeoLoad main window, click the button in the toolbar. Select "UserStreaming" in the "Virtual Users" list. Next, click the button in the validation window. The validation proceeds until either the GE stock reaches 31, or the timeout set during the recording has been reached (think time for the page UNSUBSCRIBE_1). In the example below, the GE stock reached 31, thereby triggering the JavaScript which stopped the Virtual User.