From fc8462bef1d6ef45b5e473920596d44a0cf5fc29 Mon Sep 17 00:00:00 2001 From: xiongziliang <771730766@qq.com> Date: Sat, 23 Jan 2021 09:42:45 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E6=80=A7=E8=83=BD=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E5=B7=A5=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_bench_proxy.cpp | 153 ++++++++++++++++++++++++++ tests/test_bench_pull.cpp | 185 +++++++++++++++++++++++++++++++ tests/test_bench_push.cpp | 217 +++++++++++++++++++++++++++++++++++++ tests/test_benchmark.cpp | 78 ------------- tests/test_proxy.cpp | 44 -------- 5 files changed, 555 insertions(+), 122 deletions(-) create mode 100644 tests/test_bench_proxy.cpp create mode 100644 tests/test_bench_pull.cpp create mode 100644 tests/test_bench_push.cpp delete mode 100644 tests/test_benchmark.cpp delete mode 100644 tests/test_proxy.cpp diff --git a/tests/test_bench_proxy.cpp b/tests/test_bench_proxy.cpp new file mode 100644 index 00000000..33b9a1d3 --- /dev/null +++ b/tests/test_bench_proxy.cpp @@ -0,0 +1,153 @@ +#include +#include +#include +#include "Util/CMD.h" +#include "Util/logger.h" +#include "Common/config.h" +#include "Player/PlayerProxy.h" +#include "Thread/WorkThreadPool.h" + +using namespace std; +using namespace toolkit; +using namespace mediakit; + +class CMD_main : public CMD { +public: + CMD_main() { + _parser.reset(new OptionParser(nullptr)); + + (*_parser) << Option('l',/*该选项简称,如果是\x00则说明无简称*/ + "level",/*该选项全称,每个选项必须有全称;不得为null或空字符串*/ + Option::ArgRequired,/*该选项后面必须跟值*/ + to_string(LTrace).data(),/*该选项默认值*/ + false,/*该选项是否必须赋值,如果没有默认值且为ArgRequired时用户必须提供该参数否则将抛异常*/ + "日志等级,LTrace~LError(0~4)",/*该选项说明文字*/ + nullptr); + + + (*_parser) << Option('t',/*该选项简称,如果是\x00则说明无简称*/ + "threads",/*该选项全称,每个选项必须有全称;不得为null或空字符串*/ + Option::ArgRequired,/*该选项后面必须跟值*/ + to_string(thread::hardware_concurrency()).data(),/*该选项默认值*/ + false,/*该选项是否必须赋值,如果没有默认值且为ArgRequired时用户必须提供该参数否则将抛异常*/ + "启动事件触发线程数",/*该选项说明文字*/ + nullptr); + + (*_parser) << Option('i',/*该选项简称,如果是\x00则说明无简称*/ + "in",/*该选项全称,每个选项必须有全称;不得为null或空字符串*/ + Option::ArgRequired,/*该选项后面必须跟值*/ + nullptr,/*该选项默认值*/ + true,/*该选项是否必须赋值,如果没有默认值且为ArgRequired时用户必须提供该参数否则将抛异常*/ + "拉流url,支持rtsp/rtmp/hls",/*该选项说明文字*/ + nullptr); + + (*_parser) << Option('c',/*该选项简称,如果是\x00则说明无简称*/ + "count",/*该选项全称,每个选项必须有全称;不得为null或空字符串*/ + Option::ArgRequired,/*该选项后面必须跟值*/ + "1000",/*该选项默认值*/ + true,/*该选项是否必须赋值,如果没有默认值且为ArgRequired时用户必须提供该参数否则将抛异常*/ + "拉流拉流代理个数",/*该选项说明文字*/ + nullptr); + + (*_parser) << Option('d',/*该选项简称,如果是\x00则说明无简称*/ + "delay",/*该选项全称,每个选项必须有全称;不得为null或空字符串*/ + Option::ArgRequired,/*该选项后面必须跟值*/ + "50",/*该选项默认值*/ + true,/*该选项是否必须赋值,如果没有默认值且为ArgRequired时用户必须提供该参数否则将抛异常*/ + "启动拉流代理间隔,单位毫秒",/*该选项说明文字*/ + nullptr); + + (*_parser) << Option('m',/*该选项简称,如果是\x00则说明无简称*/ + "merge",/*该选项全称,每个选项必须有全称;不得为null或空字符串*/ + Option::ArgRequired,/*该选项后面必须跟值*/ + "300",/*该选项默认值*/ + true,/*该选项是否必须赋值,如果没有默认值且为ArgRequired时用户必须提供该参数否则将抛异常*/ + "合并写毫秒,合并写能提高性能",/*该选项说明文字*/ + nullptr); + + (*_parser) << Option('T',/*该选项简称,如果是\x00则说明无简称*/ + "rtp",/*该选项全称,每个选项必须有全称;不得为null或空字符串*/ + Option::ArgRequired,/*该选项后面必须跟值*/ + to_string((int) (Rtsp::RTP_TCP)).data(),/*该选项默认值*/ + true,/*该选项是否必须赋值,如果没有默认值且为ArgRequired时用户必须提供该参数否则将抛异常*/ + "rtsp拉流方式,支持tcp/udp/multicast:0/1/2",/*该选项说明文字*/ + nullptr); + + (*_parser) << Option('D',/*该选项简称,如果是\x00则说明无简称*/ + "demand",/*该选项全称,每个选项必须有全称;不得为null或空字符串*/ + Option::ArgRequired,/*该选项后面必须跟值*/ + "1",/*该选项默认值*/ + true,/*该选项是否必须赋值,如果没有默认值且为ArgRequired时用户必须提供该参数否则将抛异常*/ + "是否按需转协议,设置为1提高性能",/*该选项说明文字*/ + nullptr); + + + } + + ~CMD_main() override {} + + const char *description() const override { + return "主程序命令参数"; + } +}; + +//此程序为zlm的拉流代理性能测试工具,用于测试拉流代理性能 +int main(int argc, char *argv[]) { + { + CMD_main cmd_main; + try { + cmd_main.operator()(argc, argv); + } catch (ExitException &) { + return 0; + } catch (std::exception &ex) { + cout << ex.what() << endl; + return -1; + } + + int threads = cmd_main["threads"]; + LogLevel logLevel = (LogLevel) cmd_main["level"].as(); + logLevel = MIN(MAX(logLevel, LTrace), LError); + auto in_url = cmd_main["in"]; + auto rtp_type = cmd_main["rtp"].as(); + auto delay_ms = cmd_main["delay"].as(); + auto proxy_count = cmd_main["count"].as(); + auto merge_ms = cmd_main["merge"].as(); + auto demand = cmd_main["demand"].as(); + + //设置日志 + Logger::Instance().add(std::make_shared("ConsoleChannel", logLevel)); + //启动异步日志线程 + Logger::Instance().setWriter(std::make_shared()); + + //设置线程数 + EventPollerPool::setPoolSize(threads); + WorkThreadPool::setPoolSize(threads); + + //设置合并写 + mINI::Instance()[General::kMergeWriteMS] = merge_ms; + mINI::Instance()[General::kRtspDemand] = demand; + mINI::Instance()[General::kRtmpDemand] = demand; + mINI::Instance()[General::kHlsDemand] = demand; + mINI::Instance()[General::kTSDemand] = demand; + mINI::Instance()[General::kFMP4Demand] = demand; + + map proxyMap; + for (auto i = 0; i < proxy_count; ++i) { + auto stream = to_string(i); + PlayerProxy::Ptr player(new PlayerProxy(DEFAULT_VHOST, "live", stream, false, false)); + (*player)[kRtpType] = rtp_type; + player->play(in_url); + proxyMap.emplace(stream, player); + //休眠后再启动下一个拉流代理,防止短时间海量链接 + if (delay_ms > 0) { + usleep(1000 * delay_ms); + } + } + + static semaphore sem; + signal(SIGINT, [](int) { sem.post(); });// 设置退出信号 + sem.wait(); + } + return 0; +} + diff --git a/tests/test_bench_pull.cpp b/tests/test_bench_pull.cpp new file mode 100644 index 00000000..872f5527 --- /dev/null +++ b/tests/test_bench_pull.cpp @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved. + * + * This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit). + * + * Use of this source code is governed by MIT license that can be found in the + * LICENSE file in the root of the source tree. All contributing project authors + * may be found in the AUTHORS file in the root of the source tree. + */ + +#include +#include +#include +#include "Util/logger.h" +#include "Util/onceToken.h" +#include "Util/CMD.h" +#include "Rtsp/UDPServer.h" +#include "Thread/WorkThreadPool.h" +#include "Player/PlayerProxy.h" + +using namespace std; +using namespace toolkit; +using namespace mediakit; + +class CMD_main : public CMD { +public: + CMD_main() { + _parser.reset(new OptionParser(nullptr)); + + (*_parser) << Option('l',/*该选项简称,如果是\x00则说明无简称*/ + "level",/*该选项全称,每个选项必须有全称;不得为null或空字符串*/ + Option::ArgRequired,/*该选项后面必须跟值*/ + to_string(LTrace).data(),/*该选项默认值*/ + false,/*该选项是否必须赋值,如果没有默认值且为ArgRequired时用户必须提供该参数否则将抛异常*/ + "日志等级,LTrace~LError(0~4)",/*该选项说明文字*/ + nullptr); + + + (*_parser) << Option('t',/*该选项简称,如果是\x00则说明无简称*/ + "threads",/*该选项全称,每个选项必须有全称;不得为null或空字符串*/ + Option::ArgRequired,/*该选项后面必须跟值*/ + to_string(thread::hardware_concurrency()).data(),/*该选项默认值*/ + false,/*该选项是否必须赋值,如果没有默认值且为ArgRequired时用户必须提供该参数否则将抛异常*/ + "启动事件触发线程数",/*该选项说明文字*/ + nullptr); + + (*_parser) << Option('i',/*该选项简称,如果是\x00则说明无简称*/ + "in",/*该选项全称,每个选项必须有全称;不得为null或空字符串*/ + Option::ArgRequired,/*该选项后面必须跟值*/ + nullptr,/*该选项默认值*/ + true,/*该选项是否必须赋值,如果没有默认值且为ArgRequired时用户必须提供该参数否则将抛异常*/ + "拉流url,支持rtsp/rtmp/hls",/*该选项说明文字*/ + nullptr); + + (*_parser) << Option('c',/*该选项简称,如果是\x00则说明无简称*/ + "count",/*该选项全称,每个选项必须有全称;不得为null或空字符串*/ + Option::ArgRequired,/*该选项后面必须跟值*/ + "1000",/*该选项默认值*/ + true,/*该选项是否必须赋值,如果没有默认值且为ArgRequired时用户必须提供该参数否则将抛异常*/ + "拉流播放器个数",/*该选项说明文字*/ + nullptr); + + (*_parser) << Option('d',/*该选项简称,如果是\x00则说明无简称*/ + "delay",/*该选项全称,每个选项必须有全称;不得为null或空字符串*/ + Option::ArgRequired,/*该选项后面必须跟值*/ + "10",/*该选项默认值*/ + true,/*该选项是否必须赋值,如果没有默认值且为ArgRequired时用户必须提供该参数否则将抛异常*/ + "启动拉流客户端间隔,单位毫秒",/*该选项说明文字*/ + nullptr); + + (*_parser) << Option('T',/*该选项简称,如果是\x00则说明无简称*/ + "rtp",/*该选项全称,每个选项必须有全称;不得为null或空字符串*/ + Option::ArgRequired,/*该选项后面必须跟值*/ + to_string((int) (Rtsp::RTP_TCP)).data(),/*该选项默认值*/ + true,/*该选项是否必须赋值,如果没有默认值且为ArgRequired时用户必须提供该参数否则将抛异常*/ + "rtsp拉流方式,支持tcp/udp/multicast:0/1/2",/*该选项说明文字*/ + nullptr); + } + + ~CMD_main() override {} + + const char *description() const override { + return "主程序命令参数"; + } +}; + +//此程序用于拉流播放性能测试 +int main(int argc, char *argv[]) { + CMD_main cmd_main; + try { + cmd_main.operator()(argc, argv); + } catch (ExitException &) { + return 0; + } catch (std::exception &ex) { + cout << ex.what() << endl; + return -1; + } + + int threads = cmd_main["threads"]; + LogLevel logLevel = (LogLevel) cmd_main["level"].as(); + logLevel = MIN(MAX(logLevel, LTrace), LError); + auto in_url = cmd_main["in"]; + auto rtp_type = cmd_main["rtp"].as(); + auto delay_ms = cmd_main["delay"].as(); + auto player_count = cmd_main["count"].as(); + + //设置日志 + Logger::Instance().add(std::make_shared("ConsoleChannel", logLevel)); + //启动异步日志线程 + Logger::Instance().setWriter(std::make_shared()); + + //设置线程数 + EventPollerPool::setPoolSize(threads); + WorkThreadPool::setPoolSize(threads); + + //播放器map + recursive_mutex mtx; + unordered_map player_map; + + auto add_player = [&]() { + auto player = std::make_shared(); + auto tag = player.get(); + player->setOnCreateSocket([](const EventPoller::Ptr &poller) { + //socket关闭互斥锁,提高性能 + return std::make_shared(poller, false); + }); + //设置播放失败监听 + player->setOnPlayResult([&mtx, &player_map, tag](const SockException &ex) { + if (ex) { + //播放失败,移除之 + lock_guard lck(mtx); + player_map.erase(tag); + } + }); + //设置播放中途断开监听 + player->setOnShutdown([&mtx, &player_map, tag](const SockException &ex) { + //播放中途失败,移除之 + lock_guard lck(mtx); + player_map.erase(tag); + }); + //设置为性能测试模式 + (*player)[kBenchmarkMode] = true; + //设置rtsp拉流方式(在rtsp拉流时有效) + (*player)[kRtpType] = rtp_type; + //发起播放请求 + player->play(in_url); + + //保持对象不销毁 + lock_guard lck(mtx); + player_map.emplace(tag, std::move(player)); + + //休眠后再启动下一个播放,防止短时间海量链接 + if (delay_ms > 0) { + usleep(1000 * delay_ms); + } + }; + + //添加这么多播放器 + for (auto i = 0; i < player_count; ++i) { + add_player(); + } + + // 设置退出信号 + static bool exit_flag = false; + signal(SIGINT, [](int) { exit_flag = true; }); + while (!exit_flag) { + //休眠一秒打印 + sleep(1); + + int alive_player = 0; + { + lock_guard lck(mtx); + alive_player = player_map.size(); + } + InfoL << "在线播放器个数:" << alive_player; + int re_try = player_count - alive_player; + while (re_try--) { + //有些播放器播放失败了,那么我们重试添加 + add_player(); + } + } + + return 0; +} + diff --git a/tests/test_bench_push.cpp b/tests/test_bench_push.cpp new file mode 100644 index 00000000..619b5bc8 --- /dev/null +++ b/tests/test_bench_push.cpp @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved. + * + * This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit). + * + * Use of this source code is governed by MIT license that can be found in the + * LICENSE file in the root of the source tree. All contributing project authors + * may be found in the AUTHORS file in the root of the source tree. + */ + +#include +#include +#include +#include "Util/logger.h" +#include "Util/onceToken.h" +#include "Util/CMD.h" +#include "Rtsp/Rtsp.h" +#include "Thread/WorkThreadPool.h" +#include "Pusher/MediaPusher.h" +#include "Player/PlayerProxy.h" + +using namespace std; +using namespace toolkit; +using namespace mediakit; + +class CMD_main : public CMD { +public: + CMD_main() { + _parser.reset(new OptionParser(nullptr)); + + (*_parser) << Option('l',/*该选项简称,如果是\x00则说明无简称*/ + "level",/*该选项全称,每个选项必须有全称;不得为null或空字符串*/ + Option::ArgRequired,/*该选项后面必须跟值*/ + to_string(LTrace).data(),/*该选项默认值*/ + false,/*该选项是否必须赋值,如果没有默认值且为ArgRequired时用户必须提供该参数否则将抛异常*/ + "日志等级,LTrace~LError(0~4)",/*该选项说明文字*/ + nullptr); + + + (*_parser) << Option('t',/*该选项简称,如果是\x00则说明无简称*/ + "threads",/*该选项全称,每个选项必须有全称;不得为null或空字符串*/ + Option::ArgRequired,/*该选项后面必须跟值*/ + to_string(thread::hardware_concurrency()).data(),/*该选项默认值*/ + false,/*该选项是否必须赋值,如果没有默认值且为ArgRequired时用户必须提供该参数否则将抛异常*/ + "启动事件触发线程数",/*该选项说明文字*/ + nullptr); + + (*_parser) << Option('i',/*该选项简称,如果是\x00则说明无简称*/ + "in",/*该选项全称,每个选项必须有全称;不得为null或空字符串*/ + Option::ArgRequired,/*该选项后面必须跟值*/ + nullptr,/*该选项默认值*/ + true,/*该选项是否必须赋值,如果没有默认值且为ArgRequired时用户必须提供该参数否则将抛异常*/ + "拉流url,支持rtsp/rtmp/hls",/*该选项说明文字*/ + nullptr); + + (*_parser) << Option('o',/*该选项简称,如果是\x00则说明无简称*/ + "out",/*该选项全称,每个选项必须有全称;不得为null或空字符串*/ + Option::ArgRequired,/*该选项后面必须跟值*/ + nullptr,/*该选项默认值*/ + true,/*该选项是否必须赋值,如果没有默认值且为ArgRequired时用户必须提供该参数否则将抛异常*/ + "推流url,支持rtsp/rtmp",/*该选项说明文字*/ + nullptr); + + (*_parser) << Option('c',/*该选项简称,如果是\x00则说明无简称*/ + "count",/*该选项全称,每个选项必须有全称;不得为null或空字符串*/ + Option::ArgRequired,/*该选项后面必须跟值*/ + "1000",/*该选项默认值*/ + true,/*该选项是否必须赋值,如果没有默认值且为ArgRequired时用户必须提供该参数否则将抛异常*/ + "推流客户端个数",/*该选项说明文字*/ + nullptr); + + (*_parser) << Option('d',/*该选项简称,如果是\x00则说明无简称*/ + "delay",/*该选项全称,每个选项必须有全称;不得为null或空字符串*/ + Option::ArgRequired,/*该选项后面必须跟值*/ + "50",/*该选项默认值*/ + true,/*该选项是否必须赋值,如果没有默认值且为ArgRequired时用户必须提供该参数否则将抛异常*/ + "启动推流客户端间隔,单位毫秒",/*该选项说明文字*/ + nullptr); + + (*_parser) << Option('m',/*该选项简称,如果是\x00则说明无简称*/ + "merge",/*该选项全称,每个选项必须有全称;不得为null或空字符串*/ + Option::ArgRequired,/*该选项后面必须跟值*/ + "300",/*该选项默认值*/ + true,/*该选项是否必须赋值,如果没有默认值且为ArgRequired时用户必须提供该参数否则将抛异常*/ + "推流合并写毫秒,合并写能提高性能",/*该选项说明文字*/ + nullptr); + + (*_parser) << Option('T',/*该选项简称,如果是\x00则说明无简称*/ + "rtp",/*该选项全称,每个选项必须有全称;不得为null或空字符串*/ + Option::ArgRequired,/*该选项后面必须跟值*/ + to_string((int) (Rtsp::RTP_TCP)).data(),/*该选项默认值*/ + true,/*该选项是否必须赋值,如果没有默认值且为ArgRequired时用户必须提供该参数否则将抛异常*/ + "rtsp拉流和推流方式,支持tcp/udp:0/1",/*该选项说明文字*/ + nullptr); + } + + ~CMD_main() override {} + + const char *description() const override { + return "主程序命令参数"; + } +}; + +//此程序用于推流性能测试 +int main(int argc, char *argv[]) { + CMD_main cmd_main; + try { + cmd_main.operator()(argc, argv); + } catch (ExitException &) { + return 0; + } catch (std::exception &ex) { + cout << ex.what() << endl; + return -1; + } + + int threads = cmd_main["threads"]; + LogLevel logLevel = (LogLevel) cmd_main["level"].as(); + logLevel = MIN(MAX(logLevel, LTrace), LError); + auto in_url = cmd_main["in"]; + auto out_url = cmd_main["out"]; + auto rtp_type = cmd_main["rtp"].as(); + auto delay_ms = cmd_main["delay"].as(); + auto pusher_count = cmd_main["count"].as(); + auto merge_ms = cmd_main["merge"].as(); + auto schema = FindField(out_url.data(), nullptr, "://"); + if (schema != RTSP_SCHEMA && schema != RTMP_SCHEMA) { + cout << "推流协议只支持rtsp或rtmp!" << endl; + return -1; + } + + //设置日志 + Logger::Instance().add(std::make_shared("ConsoleChannel", logLevel)); + //启动异步日志线程 + Logger::Instance().setWriter(std::make_shared()); + + //设置线程数 + EventPollerPool::setPoolSize(threads); + WorkThreadPool::setPoolSize(threads); + + //设置合并写 + mINI::Instance()[General::kMergeWriteMS] = merge_ms; + + //添加拉流代理 + auto proxy = std::make_shared(DEFAULT_VHOST, "app", "test", false, false); + //rtsp拉流代理方式 + (*proxy)[kRtpType] = rtp_type; + //开始拉流代理 + proxy->play(in_url); + + auto get_src = [schema]() { + return MediaSource::find(schema, DEFAULT_VHOST, "app", "test"); + }; + + //推流器map + recursive_mutex mtx; + unordered_map pusher_map; + + auto add_pusher = [&](const MediaSource::Ptr &src, const string &rand_str, int index) { + auto pusher = std::make_shared(src); + auto tag = pusher.get(); + pusher->setOnCreateSocket([](const EventPoller::Ptr &poller) { + //socket关闭互斥锁,提高性能 + return std::make_shared(poller, false); + }); + //设置推流失败监听 + pusher->setOnPublished([&mtx, &pusher_map, tag](const SockException &ex) { + if (ex) { + //推流失败,移除之 + lock_guard lck(mtx); + pusher_map.erase(tag); + } + }); + //设置推流中途断开监听 + pusher->setOnShutdown([&mtx, &pusher_map, tag](const SockException &ex) { + //推流中途失败,移除之 + lock_guard lck(mtx); + pusher_map.erase(tag); + }); + //设置rtsp推流方式(在rtsp推流时有效) + (*pusher)[Client::kRtpType] = rtp_type; + //发起推流请求,每个推流端的stream_id都不一样 + string url = StrPrinter << out_url << "_" << rand_str << "_" << index; + pusher->publish(url); + + //保持对象不销毁 + lock_guard lck(mtx); + pusher_map.emplace(tag, std::move(pusher)); + + //休眠后再启动下一个推流,防止短时间海量链接 + if (delay_ms > 0) { + usleep(1000 * delay_ms); + } + }; + + // 设置退出信号 + static bool exit_flag = false; + signal(SIGINT, [](int) { exit_flag = true; }); + while (!exit_flag) { + //休眠一秒打印 + sleep(1); + + int alive_pusher = 0; + { + lock_guard lck(mtx); + alive_pusher = pusher_map.size(); + } + InfoL << "在线推流器个数:" << alive_pusher; + auto src = get_src(); + for(auto i = 0; i < pusher_count - alive_pusher && src && !exit_flag; ++i){ + //有些推流器失败了,那么我们重试添加 + add_pusher(get_src(), makeRandStr(8), i); + } + } + + return 0; +} + diff --git a/tests/test_benchmark.cpp b/tests/test_benchmark.cpp deleted file mode 100644 index 595db720..00000000 --- a/tests/test_benchmark.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved. - * - * This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit). - * - * Use of this source code is governed by MIT license that can be found in the - * LICENSE file in the root of the source tree. All contributing project authors - * may be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include -#include "Util/logger.h" -#include "Util/onceToken.h" -#include "Rtsp/UDPServer.h" -#include "Network/sockutil.h" -#include "Poller/EventPoller.h" -#include "Player/PlayerProxy.h" - -using namespace std; -using namespace toolkit; -using namespace mediakit; - -int main(int argc, char *argv[]) { - //设置退出信号处理函数 - static semaphore sem; - signal(SIGINT, [](int) { sem.post(); });// 设置退出信号 - - //设置日志 - Logger::Instance().add(std::make_shared()); - Logger::Instance().setWriter(std::make_shared()); - - if (argc != 5) { - ErrorL << "\r\n测试方法:./test_benchmark player_count play_interval rtxp_url rtp_type\r\n" - << "例如你想每隔50毫秒启动共计100个播放器(tcp方式播放rtsp://127.0.0.1/live/0 )可以输入以下命令:\r\n" - << "./test_benchmark 100 50 rtsp://127.0.0.1/live/0 0\r\n" - << endl; - return 0; - - } - list playerList; - auto playerCnt = atoi(argv[1]);//启动的播放器个数 - atomic_int alivePlayerCnt(0); - - //由于所有播放器都是再一个timer里面创建的,默认情况下所有播放器会绑定该timer所在的poller线程 - //为了提高性能,poller分配策略关闭优先返回当前线程的策略 - EventPollerPool::Instance().preferCurrentThread(false); - - //每隔若干毫秒启动一个播放器(如果一次性全部启动,服务器和客户端可能都承受不了) - Timer timer0(atoi(argv[2])/1000.0f,[&]() { - MediaPlayer::Ptr player(new MediaPlayer()); - player->setOnPlayResult([&](const SockException &ex) { - if (!ex) { - ++alivePlayerCnt; - } - }); - player->setOnShutdown([&](const SockException &ex) { - --alivePlayerCnt; - }); - (*player)[kBenchmarkMode] = true; - (*player)[kRtpType] = atoi(argv[4]); - player->play(argv[3]); - playerList.push_back(player); - return playerCnt--; - }, nullptr); - - - Timer timer1(1,[&]() { - InfoL << "存活播放器个数:" << alivePlayerCnt.load(); - return true; - }, nullptr); - - sem.wait(); - return 0; -} - diff --git a/tests/test_proxy.cpp b/tests/test_proxy.cpp deleted file mode 100644 index 9475d562..00000000 --- a/tests/test_proxy.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include -#include -#include -#include "Util/logger.h" -#include "Network/TcpServer.h" -#include "Common/config.h" -#include "Player/PlayerProxy.h" -#include "Http/WebSocketSession.h" - -using namespace std; -using namespace toolkit; -using namespace mediakit; - -//此程序为zlm的拉流代理性能测试工具,用于测试拉流代理性能 -int main(int argc, char *argv[]) { - { - Logger::Instance().add(std::make_shared()); - Logger::Instance().setWriter(std::make_shared()); - - EventPollerPool::Instance().preferCurrentThread(false); - mINI::Instance()[General::kRtspDemand] = atoi(argv[3]); - mINI::Instance()[General::kRtmpDemand] = atoi(argv[3]); - mINI::Instance()[General::kHlsDemand] = 1; - mINI::Instance()[General::kTSDemand] = 1; - mINI::Instance()[General::kFMP4Demand] = 1; - - string url = argv[1]; - int count = atoi(argv[2]); - map proxyMap; - for (auto i = 0; i < count; ++i) { - auto stream = to_string(i); - PlayerProxy::Ptr player(new PlayerProxy(DEFAULT_VHOST, "live", stream, false, false)); - (*player)[kRtpType] = Rtsp::RTP_TCP; - player->play(url); - proxyMap.emplace(stream, player); - } - - static semaphore sem; - signal(SIGINT, [](int) { sem.post(); });// 设置退出信号 - sem.wait(); - } - return 0; -} -