title: Processing JMeter WebSocket Sampler's response
body: <p>I am a novice at programming and having necessity to write program for doing load testing with JMeter, since I cannot find the existing GUI tool to perform what I want to do.</p>
  
  <p>I am trying to load test an WebSocket application by using JMeter plugin “<a href="https://github.com/maciejzaleski/JMeter-WebSocketSampler/blob/master/README.md" rel="nofollow noreferrer">JMeter WebSocket Sampler</a>”.</p>
  
  <p>I need advise how I should process the messages sent from the WebSocket server.</p>
  
  <p>Here are some conditions. </p>
  
  <ol>
  <li>After establish the connection with a WebSocket server, server sends JMeter messages in an arbitrary timing.</li>
  <li>When JMeter receives a message, it has to return message to notify the message is received.</li>
  <li>Based on a message contents from the server, JMeter has to modify local variables.</li>
  </ol>
  
  <p>Here is my current JMeter configuration overview.</p>
  
  <ol>
  <li><p>Use <a href="https://www.blazemeter.com/blog/how-to-use-the-parallel-controller-in-jmeter" rel="nofollow noreferrer">Parallel Controller</a> to divide thread for receiving message and sending message. </p></li>
  <li><p>In receiving message thread, I tried to use <a href="https://jmeter.apache.org/usermanual/component_reference.html#JSR223_Listener" rel="nofollow noreferrer">JSR223 Listner</a> under empty WebSocket sampler to write JavaScript to process the received data. Server sends the data in JSON format.</p></li>
  <li><p>On sending message thread, I use While Loop controller, which will wait until variable value to be changed, in receiving message thread, based on server's message.</p></li>
  </ol>
  
  <p>For example, when server sends a message "Event_A_Notify" to JMeter, receiving message thread check and set Event variable to "A". Then, sending message thread will send "Event_A_Received" to the server.</p>
  
  <p>The part I'm having problem is how to handle the received messages.</p>
  
  <p>In JSR223 Lisner, I can use <a href="https://jmeter.apache.org/api/org/apache/jmeter/samplers/SampleResult.html" rel="nofollow noreferrer">sampleResult.getResponseDataAsString()</a> method to retrieve the messages from WebSocket server in string format.</p>
  
  <p>Here is a what the data looks like. (I modified the content to make it look simple. Actual message content is larger with more property).</p>
  
  <pre><code>[Message 1]
  {"Sample1":"A","uuid":"a5c77959-0284-40eb-9523-8706c947b620"}
  
  [Message 2]
  {"Sample2":"B","uuid":"93330fff-13fe-4040-9fe7-0e6d7054ee4a"}    
  
  [Message 3]
  {"Sample3":"C","uuid":"099cea81-6f8f-4417-b0c5-29199f42a6f3"}    
  
  [Message 4]
  {"Sample4":"D","uuid":"01bf3c23-87cb-41cb-ab04-1a9613a508a1"}    
  </code></pre>
  
  <p>When the received message exceeds 10, JMeter removes the older message to keep the 10 most recent messages.</p>
  
  <pre><code>[Message 8]
  {"Sample8":"H","uuid":"01bf3c23-87cb-41cb-ab04-1a9613a508a1"} 
  
  [Message 9]
  {"Sample9":"I","uuid":"01bf3c23-87cb-41cb-ab04-1a9613a508a2"} 
  
  [Message 10]
  {"Sample10":"J","uuid":"01bf3c23-87cb-41cb-ab04-1a9613a508a3"} 
  
  [Message 11]
  {"Sample11":"K","uuid":"01bf3c23-87cb-41cb-ab04-1a9613a508a4"} 
  
  [Message 12]
  {"Sample12":"L","uuid":"01bf3c23-87cb-41cb-ab04-1a9613a508a5"} 
  
  [Message 13]
  {"Sample13":"M","uuid":"01bf3c23-87cb-41cb-ab04-1a9613a508a6"} 
  
  [Message 14]
  {"Sample14":"N","uuid":"01bf3c23-87cb-41cb-ab04-1a9613a508a7"} 
  
  [Message 15]
  {"Sample15":"O","uuid":"01bf3c23-87cb-41cb-ab04-1a9613a508a8"} 
  
  [Message 16]
  {"Sample16":"P","uuid":"01bf3c23-87cb-41cb-ab04-1a9613a508a9"} 
  
  [Message 17]
  {"Sample17":"Q","uuid":"01bf3c23-87cb-41cb-ab04-1a9613a50810"} 
  </code></pre>
  
  <p>Here is the contents of JSR223 Listner to process the received message.</p>
  
  <p>Basically, I do followings.</p>
  
  <ol>
  <li>Use <em>sampleResult.getResponseDataAsString();</em> to retrieve the response.</li>
  <li>Use <em>String(responseData).split(/[Message [0-9]+]/);</em> and to split the string into array of messages by removing [Message \d].</li>
  <li>Use array object messageArray to store all the response from the WebSocket server. And process one by one in the for loop.</li>
  </ol>
  
  <blockquote>
  <pre><code>var responseData = sampleResult.getResponseDataAsString();
  
  var counter = parseInt(vars.get("counter1"));
  
  var messageList = new String(responseData).split(/\[Message [0-9]+\]/);
  
  messageList.shift();
  
  var messageArray = vars.getObject("messageArray");
  
  messageList.forEach(function(message, index) {
      if (messageArray.indexOf(message) &gt;= 0) {
       return true;
    }
    else {
       messageArray.push(message);
    }
  });
  
  for (i = counter; i &lt; messageArray.length; i++) {
  
      if (messageArray[i].match(/(someEvent).*/)) {
           vars.put("userVariable",true);
         counter += 1;
         break;
     }
     else {
            vars.put("userVariable",false);
        counter += 1;
     }
  }
  
  vars.put("counter1",counter);
  vars.putObject("messageArray", messageArray);
  </code></pre>
  </blockquote>
  
  <p>The problem with this code are:</p>
  
  <ol>
  <li>Since the messageArray object stores all messages, messageArray becomes too large and JMeter will crash eventually by OutOfMemory exception.</li>
  <li>The code to check if the received message exists in the messageArray is too slow, and performance decline exponentially as the number of messages stored increases.</li>
  </ol>
  
  <p>Could someone please adivse the more efficient and smarter way to handle WebSocket messages in the JMeter?</p>
  
  <p>I really appreciate your input.</p>
  
  <p>Thanks,</p>
  
  <p>Best Regards,</p>