2017-02-23 36 views
1

我們已經通過WebSockets爲我們的應用程序構建了發佈/訂閱模型,因此用戶可以在數據更改時接收「動態更新」。我現在正在使用JMeter來加載測試。JMeter WebSockets發佈/訂閱 - 腳本異步響應

有沒有一種方法來配置JMeter測試,以應對收到的WebSocket的「發佈」的消息,然後運行進一步採樣即做出進一步的Web請求?

我已經看過插件樣本,但他們似乎集中在請求/響應模式(例如https://bitbucket.org/pjtr/jmeter-websocket-samplers),而不是發佈/訂閱。

編輯:

我已經進展使用WebSocketSampler了一個解決方案 - 爲例JMX文件可以發現on BitBucket其使用STOMP過的WebSockets幷包括連接,從訂閱,手柄發佈消息和啓動JMeter的取樣那。

+0

嘗試使用ZebraTester。它支持websocket – Vinit

+1

@Vinit謝謝 - 我會檢查出來 - 如果你知道ZebraTest支持異步(回調)風格的用法,JMeter支持WebSockets(通過插件),這將有所幫助。由於我們已經在JMeter投入了時間,所以我很想看看我能否先做好這項工作。 – Dazed

+0

如果您正在通過網絡套接字討論MQTT,那麼即將推出的ZebraTester版本將提供 – Vinit

回答

1

它是一種誤解的是,https://bitbucket.org/pjtr/jmeter-websocket-samplers/overview插件只支持請求 - 響應模型的會話。

從版本0.7開始,插件提供「單次讀取」和「單次寫入」採樣器。當然,這取決於你的確切協議,但想法是你可以使用「單寫」採樣器發送模擬創建訂閱的WebSocket消息,然後將(標準JMeter)While循環與「single閱讀「採樣器,閱讀任何數量的正在發佈的消息。

如果這不能滿足您的需求,讓我知道,我會看看我能爲你做什麼(我是這個插件的作者)。

+0

我錯過了 - 我會仔細看看。 – Dazed

+0

按照編輯的問題 - 我已經使用WebSocketSamplers進行了改進,包括在消息接收時啓動JMeter採樣器,因此接受這個作爲我的問題的答案。 – Dazed

0

基本上,JMeter並不適合與被測系統進行異步類型的交互。

雖然(幾乎)一切皆有可能用腳本組件(後置處理器,定時器,斷言,也許採樣,似乎看你的情況最有用)和JMeter的邏輯控制器。

一樣,你可以排隊你的「進一步採樣器」,覆蓋如果塊,分析了「收到的WebSocket已發行消息」,並設置標誌變量/其他參數如果塊。

你甚至可以同步線程,如果你需要它,檢查this answer

但告訴你什麼 - 這看起來像很多手寫的東西要做。

因此,考慮整個自定義手寫測試工具也是有意義的。

+0

謝謝 - 我正在考慮同樣的線條(沒有深入細節) - 只是希望我錯過了一些東西。我會看看你鏈接的「線程間」選項。看起來非常有趣的 – Dazed

0

我用STOMP系統。所以客戶端執行HTTP消息,並通過這個訂閱模型的異步WebSocket獲得實際狀態。爲了模擬這種行爲我寫了通過JMeterContext變量可以用JMeter線程交換數據的類(進口部分你可以自己找到進口org.springframework。*):

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); 
} 

這些消息是在這個類進行處理:

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); 
       } 
      } 

     }); 
    } 

在JMeter中測試計劃,登錄階段之後我只是增加了一個BeanShell的取樣與登錄/密碼和會話串和的JMeter線程上下文

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); 

此外,可以使用通過WebSockets的數據的所有傳入與簡單瓦爾變量:

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

- 我們也使用STOMP,因此非常適合。我通過「處理程序」看到了回調 - 在那裏,當我看到設置JMeter變量時,我正在努力的是如何觸發進一步的活動 - 即如何在測試中注入更多樣本 - 對我們來說,這主要是refreshData從API通過HTTP。這需要一個LoopControl(比如說)在第一次連接併發送初始頁面請求,並且如果數據變量集(即接收到的消息)發出刷新? – Dazed

+0

沒有完全得到你的問題,但是在你建立與這個例子的連接之後,任何將來到這個明文通道的數據將可以通過變量在任何jmeter採樣器中使用。 – v0devil

+0

好的,謝謝我得到的要點 - 我的問題是關於JMeter控制結構來處理多個發佈響應,但認爲我可以解決它。 – Dazed