天天看點

JMeter擴充Java請求實作WebRTC本地音視訊推流壓測腳本

WebRTC是Web Real-Time Communication縮寫,指網頁即時通訊,是一個支援Web浏覽器進行實時語音或視訊對話的API,實作了基于網頁的視訊會議,比如聲網的Agora Web SDK就是基于WebRTC實作音視訊通信的。與HTTP不同,WebRTC應用的主要壓力是碼流,JMeter沒有找到提供WebRTC Sampler的第三方jar包,隻能自己嘗試寫一個。

無頭浏覽器

正常情況是打開浏覽器,打開攝像頭和麥克風輸入音視訊流進行請求傳輸,測試模拟采用無頭浏覽器,讀取本地檔案作為音視訊輸入。

無頭浏覽器是指沒有界面的浏覽器,通過調用浏覽器API來模拟操作,比如Chrome在啟動時添加

--headless

,就可以進入無頭模式。

WebRTC是使用JavaScript編寫的,在前端領域生态相對來說豐富一些,有現成可用的Node庫Puppeteer來支援無頭浏覽器:

JMeter擴充Java請求實作WebRTC本地音視訊推流壓測腳本

為了讓JMeter能并發調用,需要編寫Java代碼調用Puppeteer,聽着有點想象力,實際上已經有封裝好的開源庫了:jvppeteer。

Java代碼

pom.xml

中添加依賴:

<dependency>
    <groupId>io.github.fanyong920</groupId>
    <artifactId>jvppeteer</artifactId>
    <version>1.1.2</version>
</dependency>
<dependency>
    <groupId>org.apache.jmeter</groupId>
    <artifactId>ApacheJMeter_core</artifactId>
    <version>5.3</version>
</dependency>
<dependency>
    <groupId>org.apache.jmeter</groupId>
    <artifactId>ApacheJMeter_java</artifactId>
    <version>5.3</version>
</dependency>
           

jvppeteer

是Java封裝Puppeteer包,

ApacheJMeter_core

ApacheJMeter_java

用來擴充JMeter。

建立

\src\main\java\App.java

import com.ruiyun.jvppeteer.core.Puppeteer;
import com.ruiyun.jvppeteer.core.browser.Browser;
import com.ruiyun.jvppeteer.core.page.Page;
import com.ruiyun.jvppeteer.options.LaunchOptions;
import com.ruiyun.jvppeteer.options.LaunchOptionsBuilder;
import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;

public class App implements JavaSamplerClient {
    Browser browser;

    public Arguments getDefaultParameters() {
        Arguments params = new Arguments();
        params.addArgument("chromePath", "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe");
        params.addArgument("fakeVideoPath", "D:\\test.y4m");
        params.addArgument("fakeAudioPath", "D:\\test.wav");
        params.addArgument("isHeadless", "true");
        params.addArgument("isLocalMedia", "true");
        params.addArgument("isDefaultMedia", "false");
        params.addArgument("meetingUrl", "https://test.io");
        return params;
    }

    @Override
    public void setupTest(JavaSamplerContext javaSamplerContext) {
        String chromePath = javaSamplerContext.getParameter("chromePath");
        String fakeVideoPath = javaSamplerContext.getParameter("fakeVideoPath");
        String fakeAudioPath = javaSamplerContext.getParameter("fakeAudioPath");
        String path = new String(chromePath.getBytes(), StandardCharsets.UTF_8);
        ArrayList<String> argList = new ArrayList<>();
        argList.add("--no-sandbox");
        argList.add("--disable-setuid-sandbox");
        argList.add("--ignore-certificate-errors");
        argList.add("--use-fake-ui-for-media-stream");
        argList.add("--use-fake-device-for-media-stream");
        if (javaSamplerContext.getParameter("isLocalMedia").equals("true")) {
            argList.add("--use-file-for-fake-video-capture=" + fakeVideoPath);
            argList.add("--use-file-for-fake-audio-capture=" + fakeAudioPath);
        }
        boolean isHeadless = javaSamplerContext.getParameter("isHeadless").equals("true");
        LaunchOptions options = new LaunchOptionsBuilder().withArgs(argList).withHeadless(isHeadless).withExecutablePath(path).build();
        try {
            browser = Puppeteer.launch(options);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public SampleResult runTest(JavaSamplerContext javaSamplerContext) {
        try {
            Page page = browser.newPage();
            page.goTo(javaSamplerContext.getParameter("meetingUrl"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public void teardownTest(JavaSamplerContext javaSamplerContext) {
        browser.close();
    }
}
           

App

類繼承了

JavaSamplerClient

類。

getDefaultParameters()

定義了JMeter界面參數。

setupTest()

是測試初始化,建立無頭浏覽器。

runTest()

是測試執行,通路會議URL進行推流。

teardownTest()

是測試清理,關閉無頭浏覽器。

setupTest()

teardownTest()

在運作時每個線程隻會執行一次。

無頭浏覽器核心參數配置如下:

JMeter擴充Java請求實作WebRTC本地音視訊推流壓測腳本

Java代碼寫好後,需要打成jar包提供給JMeter調用。打包過程如下:

點選右上角Project Structure:

JMeter擴充Java請求實作WebRTC本地音視訊推流壓測腳本

打開Artifacts,點選+号,填寫名字,在右邊區域輕按兩下編譯後輸出檔案目錄到左邊:

JMeter擴充Java請求實作WebRTC本地音視訊推流壓測腳本

點選OK确認後,從菜單欄找到Build Artifacts點選:

JMeter擴充Java請求實作WebRTC本地音視訊推流壓測腳本

Build就可以了:

JMeter擴充Java請求實作WebRTC本地音視訊推流壓測腳本

JMeter使用

首先需要把jar包複制到

lib\ext

目錄下,

webrtcTest.jar

位置如下:

JMeter擴充Java請求實作WebRTC本地音視訊推流壓測腳本

除了

webrtcTest.jar

,還依賴3個jar包,在

Settings\Build\Build Tools\Maven

找到

Local repository

本地倉庫目錄後打開,

jvppeteer-1.1.2.jar

存放位置如下:

JMeter擴充Java請求實作WebRTC本地音視訊推流壓測腳本

commons-compress-1.20.jar

存放位置如下:

JMeter擴充Java請求實作WebRTC本地音視訊推流壓測腳本

Java-WebSocket-1.5.0.jar

存放位置如下:

JMeter擴充Java請求實作WebRTC本地音視訊推流壓測腳本

然後打開JMeter,添加線程組,添加Java請求,選擇剛才建立的類,初始參數也加載出來了:

JMeter擴充Java請求實作WebRTC本地音視訊推流壓測腳本

預設音視訊流是這樣:

JMeter擴充Java請求實作WebRTC本地音視訊推流壓測腳本

本地音視訊流是這樣:

JMeter擴充Java請求實作WebRTC本地音視訊推流壓測腳本

腳本弄好了就可以開始對WebRTC應用進行壓測了。

小結

本文介紹了如何使用Java對Puppeteer封裝的jvppeteer,實作對WebRTC進行本地音視訊流的壓測腳本,打包成jar包後,可以在JMeter中進行擴充,通過Java請求Sampler來調用。Headless Chrome對

.y4m

格式視訊和

.wav

格式音頻支援較好,建議用這兩種格式做測試。除了這種方式外,還了解到WebRTC有個官方測試引擎Kite,可以通過Selenium Grid來做自動化測試和性能測試,等實踐後再做分享。

參考資料:

https://www.cnblogs.com/chenkx6/p/13639629.html

https://baike.baidu.com/item/WebRTC/5522744?fr=aladdin

https://github.com/puppeteer/puppeteer

https://github.com/fanyong920/jvppeteer

.y4m視訊下載下傳 https://media.xiph.org/video/derf/

繼續閱讀