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代码调用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()
在运行时每个线程只会执行一次。
无头浏览器核心参数配置如下:
Java代码写好后,需要打成jar包提供给JMeter调用。打包过程如下:
点击右上角Project Structure:
打开Artifacts,点击+号,填写名字,在右边区域双击编译后输出文件目录到左边:
点击OK确认后,从菜单栏找到Build Artifacts点击:
Build就可以了:
JMeter使用
首先需要把jar包复制到lib\ext
目录下,webrtcTest.jar
位置如下:
除了webrtcTest.jar
,还依赖3个jar包,在Settings\Build\Build Tools\Maven
找到Local repository
本地仓库目录后打开,jvppeteer-1.1.2.jar
存放位置如下:
commons-compress-1.20.jar
存放位置如下:
Java-WebSocket-1.5.0.jar
存放位置如下:
然后打开JMeter,添加线程组,添加Java请求,选择刚才创建的类,初始参数也加载出来了:
默认音视频流是这样:
本地音视频流是这样:
脚本弄好了就可以开始对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/
JMeter扩展Java请求实现WebRTC本地音视频推流压测脚本的更多相关文章
- 使用Jmeter测试java请求
1.性能测试过程中,有时候开发想对JAVA代码进行性能测试,Jmeter是支持对Java请求进行性能测试,但是需要自己开发.打包好要测试的代码,就能在Java请求中对该java方法进行性能测试2.本文 ...
- jmeter之java请求
通常情况下,推荐使用jmeter之java请求编写一beashell调用java代码(上篇)(推荐)编写Java 请求 有以下优势 脚本易维护 易调试 开发脚本周期短 不过网上扩展java请求文章比较 ...
- jmeter 的java请求代码在main方法里面执行
1.新建一个java请求执行加法类 public class TestDemo { public int Tdemo(int a,int b){ int sum = 0; sum = a+b; ret ...
- Jmeter执行Java请求
Jmeter执行Java请求(QQ交流群:577439379) 一.打开Eclipse,创建一个Java工程 二.拷贝jmeter所依赖的jar包 将jmeter中,\lib\ext目录下的Apach ...
- 一文揭秘测试平台中是如何将测试用例一键转化Jmeter压测脚本
接上篇,一键转化将接口测试平台测试用例转化成Jmeter压测脚本思路,这里我首先在java 上面做了一个简单的实验,看看 转化的中间遇到的问题,这里呢,我只是给了一个简单的demo 版本, ...
- Jmeter(四十七) - 从入门到精通高级篇 - 分布式压测部署之负载机的设置(详解教程)
1.简介 千呼万唤始出来,这一篇感觉写了好久,总想写的清楚明白简洁,但是还是洋洋洒洒写了好多,希望大家喜欢吧!本来打算将这一篇文章是放在性能测试中讲解和分享的,但是有的童鞋或者小伙伴们私下问的太多了, ...
- jmeter压测脚本编写与静态文件处理
一.压测脚本编写 概述:工具为谷歌浏览器-->F12-->Network,访问被测站点,通过其中的请求的地方来构造压测脚本 二.静态文件处理 概述:静态文件包括css/js/图片等,它们有 ...
- Jmeter自定义Java请求,继承AbstractJavaSamplerClient
首先,使用Eclipse新建一个项目,然后从Jmeter的lib/ext目录下中拷贝ApacheJMeter_java.jar和ApacheJMeter_core.jar两个文件,然后引入这两个JAR ...
- Jmeter自定义Java请求开发
一.本次实验目的 IDEA新建maven项目,使用java开发自定义jmeter的请求. 本次开发使用的代码,会百度云分享给大家. 二.本次实验环境 Idea 2017.02 Jmeter 5.1.1 ...
随机推荐
- anaconda jupyter notebook 启动方法
介绍 anaconda jupyter notebook是一种基于浏览器的python编译环境.(大概) 使用时可能因为浏览器缓存造成问题. 但是很方便. 启动方法 anaconda navigato ...
- 进程控制——fork-and-exec、system、wait
forc-and-exec流程 父进程与子进程之间的关系十分复杂,最大的复杂点在于进程间相互调用.Linux下这一流程称为fork-and-exec.父进程通过fork的方式产生一个一模一样的子进程, ...
- 6. Connection has already been closed 数据库连接被关闭
生产上Tomcat出现 Connection has already been closed.问题,但是在uat测试是好的! 遇见两次: 1.某个程序dao中执行逻辑异常复杂,有时候需要执行一分多钟, ...
- 如何使用 js 实现一个 debounce 函数
如何使用 js 实现一个 debounce 函数 原理 防抖: 是指在指定的单位时间内,如果重复触发了相同的事件,则取消上一次的事件,重新开始计时! 实现方式 "use strict&quo ...
- Build your own React
Build your own React https://pomb.us/build-your-own-react/ https://github.com/pomber/didact demo htt ...
- URLSearchParams & GET Query String & JSON
URLSearchParams & GET Query String & JSON https://developer.mozilla.org/zh-CN/docs/Web/API/U ...
- c++ winapi 在当前程序(local)调用目标程序(target)的函数
GameCheat stackoverflow 如果你的目标程序是x86/x64, 那么当前程序也需要编译为x84/x64 #include <iostream> #include < ...
- HTTP 协议的前世今生
尽人事,听天命.博主东南大学研究生在读,热爱健身和篮球,正在为两年后的秋招准备中,乐于分享技术相关的所见所得,关注公众号 @ 飞天小牛肉,第一时间获取文章更新,成长的路上我们一起进步 本文已收录于 C ...
- CloudQuery v1.2.1 版本发布
欢迎来到 CloudQuery v1.2.1 版本发布会. 上次 v1.2.0 版本发布收到广大朋友们的热烈反响,大家提出了很多宝贵建议,揪出了不少 Bug.在此,我们表示由衷感谢.问题和建议我们都会 ...
- .Net按模板导出Excel
最近在项目中遇到需求 需要按照一定的模板导出数据 还是直接上代码 这里贴一部分模板长什么样吧 然后就是代码 大致就是找到模板 复制一份临时文件 然后修改临时文件然后导出数据 代码如下 string a ...