2017-02-23 2 views
1

Wir haben ein Publish/Subscribe-Modell über WebSockets in unsere Anwendung integriert, so dass Benutzer "dynamische Updates" erhalten, wenn sich Daten ändern. Ich versuche nun, dies mit JMeter zu testen.JMeter WebSockets Publish/Subscribe - Skripting asynchrone Antworten

Gibt es eine Möglichkeit, einen JMeter-Test so zu konfigurieren, dass er auf den Empfang einer WebSocket- "published" -Nachricht reagiert und dann weitere Sampler ausführt, d. H. Weitere Webanfragen stellt?

Ich habe Plugin-Beispiele angeschaut, aber sie scheinen auf Anfrage/Antwort-Modell konzentriert (z. B. https://bitbucket.org/pjtr/jmeter-websocket-samplers) statt zu veröffentlichen/abonnieren.

Edit:

ich eine Lösung für diese die WebSocketSampler fortgeschritten sind mit - ein Beispiel JMX-Datei kann on BitBucket gefunden werden, die STOMP über WebSockets und beinhaltet auch Connect, abonnieren, Griff Nachricht veröffentlichen und Initiate JMeter Samplers aus Das.

+0

Versuchen Sie ZebraTester. Es unterstützt Websockets – Vinit

+1

@Vinit danke - ich werde das überprüfen - JMeter unterstützt WebSockets (über Plugins), wenn Sie wissen, dass ZebraTest Async (Callback) -Stil Verwendung unterstützt, die helfen würde. Da wir bereits Zeit in JMeter investiert haben, bin ich gespannt, ob ich diese Arbeit als erstes machen kann. – Dazed

+0

Wenn Sie über MQTT über Web-Sockets sprechen, wird das in der kommenden Version von ZebraTester verfügbar sein – Vinit

Antwort

1

Es ist ein Missverständnis, dass die https://bitbucket.org/pjtr/jmeter-websocket-samplers/overview Plugin unterstützt nur Request-Response-Modell Gespräche.

Seit Version 0.7 bietet das Plugin "single read" und "single write" Sampler.Natürlich hängt es von Ihrem genauen Protokoll ab, aber die Idee ist, dass Sie einen "single write" -Sampler verwenden können, um eine WebSocket-Nachricht zu senden, die das Erstellen des Abonnements simuliert und dann eine (Standard JMeter) While-Schleife in Kombination mit dem "single Lesen Sie "Sampler", um eine beliebige Anzahl von Nachrichten zu lesen, die veröffentlicht werden.

Wenn dies nicht Ihren Bedürfnissen entspricht, lassen Sie es mich wissen und ich werde sehen, was ich für Sie tun kann (ich bin der Autor dieses Plugins).

+0

Das hätte ich vermisst - ich schaue genauer hin. – Dazed

+0

Wie Bearbeiten auf Frage - Ich habe Fortschritte mit WebSocketSampler mit Aufnahme von JMeter Sampler auf den Empfang von Nachrichten und akzeptiere dies als Antwort auf meine Frage. – Dazed

0

Grundsätzlich eignet sich JMeter nicht gut für asynchrone Interaktion mit dem getesteten System.

Obwohl (virtuell) alles mit Scripting-Komponenten möglich ist (Postprozessoren, Timer, Assertions, vielleicht Sampler, scheint in Ihrem Fall am nützlichsten zu sein) und JMeter Logic Controller.

Sie können also Ihre "weiteren Sampler", die in If-Blöcken behandelt werden, in einer Liste mit dem "Empfang einer veröffentlichten WebSocket-Nachricht" aufstellen und die Flag-Variablen/andere Parameter für If-Blöcke setzen.

Und Sie können sogar Threads synchronisieren, wenn Sie es brauchen, überprüfen Sie this answer.

Aber sag dir was - das sieht ziemlich viel nach handgeschriebenen Sachen aus.

Es ist also sinnvoll, den gesamten benutzerdefinierten handschriftlichen Test-Kabelbaum zu berücksichtigen.

+0

danke - ich dachte mit die gleichen Zeilen (hatte nicht in die Details gegraben) - hatte nur gehofft, ich hätte etwas verpasst. Ich werde mir die "Inter-thread" -Option ansehen, die Sie verlinken. – Dazed

0

Ich hatte das System mit STOMP. Daher haben die Clients die HTTP-Nachrichten ausgeführt und sie haben den tatsächlichen Status über asynchrone WebSockets mit diesem Subskriptionsmodell erhalten. Um dieses Verhalten zu emulieren schrieb ich eine Klasse, die über JMeterContext variablen Daten mit Jmeter Themen austauschen konnten (Import Teil Sie selbst importieren org.springframework finden. *):

public class StompWebSocketLoadTestClient { 

public static JMeterContext ctx; 
public static StompSession session; 

public static void start(JMeterContext ctx, String wsURL, String SESSION) throws InterruptedException { 
    WebSocketClient transport = new StandardWebSocketClient(); 

    WebSocketStompClient stompClient = new WebSocketStompClient(transport); 
    ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler(); 
    threadPoolTaskScheduler.initialize(); 
    stompClient.setTaskScheduler(threadPoolTaskScheduler); 
    stompClient.setDefaultHeartbeat(new long[]{10000, 10000}); 
    stompClient.setMessageConverter(new ByteArrayMessageConverter()); 
    StompSessionHandler handler = new MySessionHandler(ctx); 
    WebSocketHttpHeaders handshakeHeaders = new WebSocketHttpHeaders(); 
    handshakeHeaders.add("Cookie", "SESSION=" + SESSION); 
    stompClient.connect(wsURL, handshakeHeaders, handler); 
    sleep(1000); 
} 

Die Meldungen in dieser Klasse behandelt wurden:

private static class MySessionHandler extends StompSessionHandlerAdapter implements TestStateListener { 

    private String Login = ""; 
    private final JMeterContext ctx_; 

    private MySessionHandler(JMeterContext ctx) { 
     this.ctx_ = ctx; 
    } 

    @Override 
    public void afterConnected(StompSession session, StompHeaders connectedHeaders) { 
     session.setAutoReceipt(true); 
     this.Login = ctx_.getVariables().get("LOGIN"); 
     //System.out.println("CONNECTED:" + connectedHeaders.getSession() + ":" + session.getSessionId() + ":" + Login); 
     //System.out.println(session.isConnected()); 
     **//HERE SUBSCRIBTION:** 
     session.subscribe("/user/notification", new StompFrameHandler() { 

      @Override 
      public Type getPayloadType(StompHeaders headers) { 
       //System.out.println("getPayloadType:"); 
       Iterator it = headers.keySet().iterator(); 
       while (it.hasNext()) { 
        String header = it.next().toString(); 

        //System.out.println(header + ":" + headers.get(header)); 
       } 
       //System.out.println("================="); 
       return byte[].class; 
      } 

      @Override 
      public void handleFrame(StompHeaders headers, Object payload) { 
       //System.out.println("recievedMessage"); 
       NotificationList nlist = null; 
       try { 
        nlist = NotificationList.parseFrom((byte[]) payload); 

        JMeterVariables vars = ctx_.getVariables(); 
        Iterator it = nlist.getNotificationList().iterator(); 
        while (it.hasNext()) { 
         Notification n = (Notification) it.next(); 
         String className = n.getType(); 
         //System.out.println("CLASS NAME:" + className); 

         if (className.contains("response.Resource")) { 
          ///After getting some message you can work with jmeter variables: 
          vars.putObject("var1", var1); 
          vars.put("var2",String.valueOf(var2)); 
         } 
         //Here is "sending" variables back to Jmeter thread context so you can use the data during the test 
         ctx_.setVariables(vars); 
         n = null; 

        } 
       } catch (InvalidProtocolBufferException ex) { 
        Logger.getLogger(StompWebSocketLoadTestClient.class.getName()).log(Level.SEVERE, null, ex); 
       } 
      } 

     }); 
    } 

In Jmeter Testplan, habe ich nach Anmeldung Stufe nur einen Sampler mit Beanshell Login/Passwort und Sitzungs Strings und Jmeter Thread-Kontext:

import jmeterstopm.StompWebSocketLoadTestClient; 
StompWebSocketLoadTestClient ssltc = new StompWebSocketLoadTestClient(); 
String SERVER_NAME = vars.get("SERVER_NAME"); 
String SESSION = vars.get("SESSION"); 
String ws_pref = vars.get("ws_pref"); 
ssltc.start(ctx,ws_pref+"://"+SERVER_NAME+"/endpoint/notification- ws/websocket",SESSION); 

Weiterhin ist möglich, alle eingehenden über Websockets Daten mit einfachen Vars Variable zu verwenden:

Object var1= (Object) vars.getObject("var1"); 
+0

das sieht sehr interessant aus - wir verwenden auch STOMP so potenziell eine gute Passform. Ich sehe den Rückruf über "Handler" - und da, während ich JMeter-Variablen einstellen sehe, ist das Bit, mit dem ich kämpfe, wie es weitere Aktivitäten auslöst - dh wie weitere Proben in den Test injiziert werden - für uns ist das hauptsächlich refreshData von API über HTTP. Würde dies ein LoopControl mit (sagen wir) Verbindung erfordern und eine erste Seitenanforderung beim ersten Durchlauf senden und wenn eine Datenvariable gesetzt (d. H. Nachricht empfangen) eine Aktualisierung ausgibt? – Dazed

+0

Haben Sie Ihre Frage nicht vollständig beantwortet, aber nachdem Sie die Verbindung mit diesem Beispiel hergestellt haben, können alle Daten, die zu diesem beschriebenen Kanal kommen, in jedem jmeter Sampler über vars verwendet werden. – v0devil

+0

Ok danke ich bekomme den Kern - Meine Frage war wirklich über JMeter-Kontrollstrukturen, um mehrere Publish-Antworten zu behandeln, aber ich denke, ich kann es ausarbeiten. – Dazed