1. Handshaking: The connection is established.

  • Communication parameters negotiation: The client and the server agree on the delivered contents, and the media contents start being delivered to the client.

  • Receiving streamed data: The client sends requests and the servers send back the next portion of data.

  • Closing active connection.

  • Rtmp Load Testing Tool

    Load Testing RTMPT Live Media Streaming With JMeter

    Now, we’ll look into each phase in detail and show how they can be implemented in the JMeter script.

    1. Handshaking

    According to the RTMPT protocol specification, all the HTTP requests the client sends to the server have to have a Content-Type header with the value application/x-fcs.

    In JMeter, add an HTTP header manager config element to the script and a Content-Type header with the value application/x-fcs to it.

    All HTTP Requests between the client and the server need to have the same parameters.

    In JMeter, add an HTTP Request Defaults config element to the script and define parameters. These parameters should be the same for all HTTP requests: server name, implementation, and protocol type.

    3. The client sends a POST HTTP request to URI /fcs/ident2, with the Content-Type header application/x-fcs. The server responds with the response code, depending on its settings for this type of request. On default, it responds with the response code 404 and the message “Not found.”

    In JMeter, add a Thread Group and an HTTP Request under it. Add the /fcs/ident2 string to the path field of the HTTP sampler.

    For simplicity, consider the server responds to this request with the response code 404.

    In JMeter, add a Response Assertion element to the script, as a child element of the HTTP sampler, to assert the 404 Response Code. Don’t forget to set the ‘Ignore status’ checkbox inside the assertion. Now add the ’If Controller’ to the script. Evaluate the last sampler result variable in the condition string.

    After the first request, the client sends a POST HTTP request to the server to open the connection. The request URI is /open/1.

    In JMeter, add an HTTP sampler and add /open/1 string to the path field of the sampler.

    The server responds to the client with an RTMPT connection ID in the body of the response, which is further used for handling requests.

    In JMeter, add the child Regexp PostProcessor component to the sampler. This will extract the connection ID from the response and save it in the JMeter variable.

    Add the ‘If logic’ controller in the script to validate that the connection_id variable is set and if it executes the further steps of the flow.

    2. Communication Parameters Negotiation

    With a series of ‘send’ commands, the client negotiates streamed data communication parameters with the server. These include the endpoint of media contents, bandwidth, chunk size, buffer size, and other parameters.

    The series starts from the HTTP request to URI /idle/connection_id/0 and continues with several HTTP requests that are transmitted to URI /send/connection_id/number. Connection_id is the id received from the server at the negotiation phase and its numbers are 1, 2, 3, 4 or 5, depending on the type of the ‘send’ command. ‘Send’ commands are sent in a sequence, starting from /send/connection_id/1 and ending with /send/connection_id/5.

    Rtmp Load Testing Tool For Mac

    In JMeter, add an HTTP sampler for the ‘idle’ command.

    In the case of success, the server responds with the response code 200. Then, five idle send commands follow.

    In the body of the HTTP request for ‘send’ commands, the client sends the AMF-encoded control blocks that control negotiations. They pass requested data from the client to the server and return negotiated data from the server. Connection parameters are specified in the RTMP protocol specification and depend on the configuration of the streaming server. We will add all these five ‘send’ commands added to the JMeter script. The first ‘send’ command initiates negotiation between the client and the server.

    According to the official documentation, the RTMP connection is established through the exchange of three packets both from the client and the server sides. Each packet is encapsulated in one HTTP request. The body of the first ‘send’ command contains 1537 bytes of data. The first byte is set to 0x03, then following four bytes represent the ‘epoch’ timestamp, but RTMP specification admits setting them to ‘0.’ The other bytes are random numbers and they may be set to ‘0’ as well.

    In JMeter, to make such HTTP request, add an HTTP sampler to the script, as shown in the screenshot below:

    To form the 1537 bytes of the body of the HTTP request, add a BeanShell preprocessor as a child element of the HTTP sampler, which represents the first ‘send’ command. The BeanShell preprocessor should implement generation of this byte array and attach this array to the HTTP sampler body.

    The server responds with a block of bytes to the first ‘send’ command. It’s necessary to save it and send it to server in the following ‘send’ command. Extracting and adding the 1537 bytes of the server response is done in the preprocessor of the next HTTP sampler. The next ‘send’ command returns the response of the previous sampler back to the server and requests the connection.

    In JMeter, add a HTTP sampler to the JMeter script. The sampler is similar to the previous one, except for the path, which is /send/<connection_id>/2. The body of this sampler is composed of the stored response of the previous request and the AMF coded block.

    Now we need to add a BeanShell preprocessor child element to this HTTP sampler. The implementation of the BeanShell preprocessor should attach bytes saved from the previous sampler response and AMF coded block, to the sampler body. For AMF coding, the third party library is used. Download the amf48 JAR file and drop it to the jmeter /lib/ext directory. The PreProcessor for this sample is shown in the screenshot below:

    The server responds with the AMF coded communication data.

    The server responds with the AMF coded communication data. from the response, we extract only the window acknowledgement size parameter.

    The next HTTP request is a send command, that passes the window acknowledgment size parameter to the server in the AMF coded form.

    In JMeter, add an HTTP sampler for this ‘send’ command, as done for the previous ones, and set the sampler path field to /send/connection_id/3. The BeanShell preprocessor for this sampler is shown in the screenshot below:

    The expected response code from the server for this HTTP request is ‘200.’

    The next ‘send’ command, which the client sends to the server, sets buffer length and creates the stream. The create stream parameter is AMF encoded.

    Rtmp Player

    In JMeter, add a HTTP sampler for this request to the JMeter script and set the path field of the sampler to the /send/<connection_id>/4.

    Add a BeanShell PreProcessor as a child element for this sampler. The contents of the preprocessor are shown in the screenshot below.

    If the stream is created, the HTTP response code is 200 and in the body of the HTTP response, the connection result code is returned. In the last ‘send’ command, the media is requested and the server returns the first blocks of streamed data. The body of this request contains the AMF coded file name and buffer length. In order to implement it, add the BeanShell preprocessor component as a child to this sampler. The server responds with the metadata and streaming data in the body of the response.

    In JMeter, add a HTTP sampler for this command and set the HTTP sampler path to /send/<connection_id>/5.

    Add a BeanShell PreProcessor as a child element to pass the AMF encoded file name and buffer length parameters to the body of the HTTP request.

    3. Receiving Streamed Data

    From this moment on, the client parses the response of the HTTP request, extracts the chunked stream, restores the streamed media and saves the data to file. Each time the next portion of data is restored, the client sends an ‘idle’ command to the server. This command is the HTTP post request that is sent to the URI /idle/connection_id/number URI. Here the number sequentially changes when each new ‘idle’ command is issued to the server, starting from 6.

    The streamed data is returned in the body of the response. To implement this part of the script in JMeter, add a While Controller and HTTP sampler under the While Controller.

    In JMeter, add a counter under the While Controller to count from 6.

    Add a BeanShell PostProcessor element as a child element of this sampler and implement it to check that the body of the HTTP sampler contains data. The empty response (when it contains no data) is the condition required to leave the loop cycle of the While Controller. This structure is shown in the screenshot below.

    To simplify the task, there is no need to add BeanShell PostProcessor elements to reconstruct the stream on the JMeter side. The purpose of load testing, in this case, is to load the streaming server with requests from the clients imitated by the JMeter script, to which the server responds with the requested media streams.

    4. Close Active Connection

    At the end of the communication, the client sends a close command to close the active connection. The command is sent as HTTP Post Request to the URI /close. The server responds with the 0x00 byte and closes the stream.

    In JMeter, add the HTTP Sampler to the JMeter script and add the string /close to the path field.

    Congratulations! This isn’t a simple solution since it requires a lot of coding work, especially to compose AFM commands that the client sends to the server and to parse parameters that server returns to the client. But you got through it!

    This example is one of the implementations of the JMeter script for load testing streaming web services that streams data over RTMPT protocol. An alternative option is to develop your own samplers, which implement RTMPT flow for working with streaming data.

    You are welcome to ask questions in the comments section below.

    performance,load testing,live media streaming,jmeter,rtmpt,tutorial
    Published at DZone with permission of Konsantine Firsanov, DZone MVB. See the original article here.
    Opinions expressed by DZone contributors are their own.