mirror of
https://github.com/ossrs/srs.git
synced 2025-02-14 20:31:56 +00:00
add librtmp bandwidth check/test client.
This commit is contained in:
parent
cf7a48e3da
commit
cc62d254f0
20 changed files with 725 additions and 87 deletions
|
@ -561,7 +561,7 @@ else
|
|||
fi
|
||||
|
||||
#####################################################################################
|
||||
# build research code
|
||||
# build research code, librtmp
|
||||
#####################################################################################
|
||||
if [ $SRS_RESEARCH = YES ]; then
|
||||
mkdir -p ${SRS_OBJS}/research
|
||||
|
@ -571,6 +571,10 @@ if [ $SRS_RESEARCH = YES ]; then
|
|||
|
||||
(cd research/ffempty && make ${SRS_JOBS} && mv ffempty ../../${SRS_OBJS}/research)
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then echo "build research/ffempty failed, ret=$ret"; exit $ret; fi
|
||||
fi
|
||||
|
||||
if [ $SRS_LIBRTMP = YES ]; then
|
||||
mkdir -p ${SRS_OBJS}/research
|
||||
|
||||
# librtmp
|
||||
(cd research/librtmp && mkdir -p objs && ln -sf `pwd`/objs ../../${SRS_OBJS}/research/librtmp)
|
||||
|
|
2
trunk/configure
vendored
2
trunk/configure
vendored
|
@ -483,7 +483,7 @@ APP_OBJS="${MODULE_OBJS[@]}"
|
|||
MODULE_ID="LIBS"
|
||||
MODULE_DEPENDS=("CORE" "KERNEL" "RTMP")
|
||||
ModuleLibIncs=(${SRS_OBJS})
|
||||
MODULE_FILES=("srs_librtmp" "srs_lib_simple_socket")
|
||||
MODULE_FILES=("srs_librtmp" "srs_lib_simple_socket" "srs_lib_bandwidth")
|
||||
LIBS_INCS="src/libs"; MODULE_DIR=${LIBS_INCS} . auto/modules.sh
|
||||
LIBS_OBJS="${MODULE_OBJS[@]}"
|
||||
#
|
||||
|
|
9
trunk/research/librtmp/Makefile
Normal file → Executable file
9
trunk/research/librtmp/Makefile
Normal file → Executable file
|
@ -3,7 +3,10 @@ GCC = gcc
|
|||
ifeq ($(HANDSHAKE),)
|
||||
ST_ALL = help
|
||||
else
|
||||
ST_ALL = objs/srs_flv_parser objs/srs_flv_injecter objs/srs_publish objs/srs_play objs/srs_ingest_flv objs/srs_ingest_rtmp objs/srs_detect_rtmp
|
||||
ST_ALL = objs/srs_flv_parser \
|
||||
objs/srs_flv_injecter objs/srs_publish objs/srs_play \
|
||||
objs/srs_ingest_flv objs/srs_ingest_rtmp objs/srs_detect_rtmp \
|
||||
objs/srs_bandwidth_check
|
||||
endif
|
||||
|
||||
.PHONY: default clean help ssl nossl
|
||||
|
@ -24,6 +27,7 @@ help:
|
|||
@echo " srs_ingest_flv ingest flv file and publish to RTMP server."
|
||||
@echo " srs_ingest_rtmp ingest RTMP and publish to RTMP server."
|
||||
@echo " srs_detect_rtmp detect RTMP stream info."
|
||||
@echo " srs_bandwidth_check bandwidth check/test tool."
|
||||
@echo "Remark: about simple/complex handshake, see: http://blog.csdn.net/win_lin/article/details/13006803"
|
||||
@echo "Remark: srs Makefile will auto invoke this by --with/without-ssl, "
|
||||
@echo " that is, if user specified ssl(by --with-ssl), srs will make this by 'make ssl'"
|
||||
|
@ -88,3 +92,6 @@ objs/srs_ingest_rtmp: srs_ingest_rtmp.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(
|
|||
|
||||
objs/srs_detect_rtmp: srs_detect_rtmp.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L)
|
||||
$(GCC) srs_detect_rtmp.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(EXTRA_CXX_FLAG) -o objs/srs_detect_rtmp
|
||||
|
||||
objs/srs_bandwidth_check: srs_bandwidth_check.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L)
|
||||
$(GCC) srs_bandwidth_check.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(EXTRA_CXX_FLAG) -o objs/srs_bandwidth_check
|
||||
|
|
113
trunk/research/librtmp/srs_bandwidth_check.c
Normal file
113
trunk/research/librtmp/srs_bandwidth_check.c
Normal file
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-2014 winlin
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
/**
|
||||
gcc srs_bandwidth_check.c ../../objs/lib/srs_librtmp.a -g -O0 -lstdc++ -o srs_bandwidth_check
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../../objs/include/srs_librtmp.h"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
int ret = 0;
|
||||
srs_rtmp_t rtmp;
|
||||
|
||||
// packet data
|
||||
int type, size;
|
||||
u_int32_t timestamp = 0;
|
||||
char* data;
|
||||
|
||||
// srs debug info.
|
||||
char srs_server[128];
|
||||
char srs_primary_authors[128];
|
||||
char srs_id[64];
|
||||
char srs_pid[64];
|
||||
char srs_server_ip[128];
|
||||
// bandwidth test data.
|
||||
int64_t start_time, end_time;
|
||||
int play_kbps, publish_kbps;
|
||||
int play_bytes, publish_bytes;
|
||||
int play_duration, publish_duration;
|
||||
|
||||
if (argc <= 1) {
|
||||
printf("RTMP bandwidth check/test with server.\n"
|
||||
"Usage: %s <rtmp_url>\n"
|
||||
" rtmp_url RTMP bandwidth url to check. format: rtmp://server:port/app?key=xxx&&vhost=xxx\n"
|
||||
"For example:\n"
|
||||
" %s rtmp://127.0.0.1:1935/app?key=35c9b402c12a7246868752e2878f7e0e,vhost=bandcheck.srs.com\n"
|
||||
"@remark, output text to stdout, while json to stderr.\n",
|
||||
argv[0], argv[0]);
|
||||
ret = 1;
|
||||
exit(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
rtmp = srs_rtmp_create2(argv[1]);
|
||||
|
||||
printf("RTMP bandwidth check/test with server.\n");
|
||||
printf("srs(simple-rtmp-server) client librtmp library.\n");
|
||||
printf("version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision());
|
||||
printf("bandwidth check/test url: %s\n", argv[1]);
|
||||
|
||||
if ((ret = srs_simple_handshake(rtmp)) != 0) {
|
||||
printf("simple handshake failed.\n");
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
printf("simple handshake success\n");
|
||||
|
||||
if ((ret = srs_connect_app(rtmp)) != 0) {
|
||||
printf("connect vhost/app failed.\n");
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
printf("connect vhost/app success\n");
|
||||
|
||||
if ((ret = srs_bandwidth_check(rtmp,
|
||||
srs_server, srs_primary_authors,
|
||||
srs_id, srs_pid, srs_server_ip,
|
||||
&start_time, &end_time, &play_kbps, &publish_kbps,
|
||||
&play_bytes, &publish_bytes, &play_duration, &publish_duration)) != 0
|
||||
) {
|
||||
printf("bandwidth check/test failed.\n");
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
printf("bandwidth check/test success\n");
|
||||
|
||||
printf("\n%s, %s\n"
|
||||
"%s, srs_pid=%s, srs_id=%s\n"
|
||||
"duration: %dms(%d+%d)\n"
|
||||
"play: %dkbps\n"
|
||||
"publish: %dkbps\n\n",
|
||||
(char*)srs_server, (char*)srs_primary_authors,
|
||||
(char*)srs_server_ip, (char*)srs_pid, (char*)srs_id,
|
||||
(int)(end_time - start_time), play_duration, publish_duration,
|
||||
play_kbps,
|
||||
publish_kbps);
|
||||
|
||||
rtmp_destroy:
|
||||
srs_rtmp_destroy(rtmp);
|
||||
|
||||
printf("terminate with ret=%d\n", ret);
|
||||
return ret;
|
||||
}
|
Binary file not shown.
|
@ -429,8 +429,7 @@ package
|
|||
publish_timeout_handler = 0;
|
||||
}
|
||||
}
|
||||
private function onSrsBandCheckFinished(evt:Object):void{
|
||||
var code:Number = evt.code;
|
||||
private function onSrsBandCheckFinished(evt:Object):void{
|
||||
var start_time:Number = evt.start_time;
|
||||
var end_time:Number = evt.end_time;
|
||||
var play_kbps:Number = evt.play_kbps;
|
||||
|
|
|
@ -68,9 +68,9 @@ void SrsBandwidthSample::calc_kbps(int _bytes, int _duration)
|
|||
* recv bandwidth helper.
|
||||
*/
|
||||
typedef bool (*_CheckPacketType)(SrsBandwidthPacket* pkt);
|
||||
bool _bandwidth_is_flash_final(SrsBandwidthPacket* pkt)
|
||||
bool _bandwidth_is_final(SrsBandwidthPacket* pkt)
|
||||
{
|
||||
return pkt->is_flash_final();
|
||||
return pkt->is_final();
|
||||
}
|
||||
bool _bandwidth_is_starting_play(SrsBandwidthPacket* pkt)
|
||||
{
|
||||
|
@ -183,7 +183,12 @@ int SrsBandwidth::do_bandwidth_check(SrsKbpsLimit* limit)
|
|||
|
||||
SrsBandwidthSample play_sample;
|
||||
SrsBandwidthSample publish_sample;
|
||||
|
||||
// timeout for a packet.
|
||||
_rtmp->set_send_timeout(play_sample.duration_ms * 1000);
|
||||
_rtmp->set_recv_timeout(publish_sample.duration_ms * 1000);
|
||||
|
||||
// start test.
|
||||
int64_t start_time = srs_get_system_time_ms();
|
||||
|
||||
// sample play
|
||||
|
@ -254,7 +259,7 @@ int SrsBandwidth::play_start(SrsBandwidthSample* sample, SrsKbpsLimit* limit)
|
|||
return ret;
|
||||
}
|
||||
}
|
||||
srs_info("BW check begin.");
|
||||
srs_info("BW check play begin.");
|
||||
|
||||
if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_starting_play)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
|
@ -424,7 +429,6 @@ int SrsBandwidth::finial(SrsBandwidthSample& play_sample, SrsBandwidthSample& pu
|
|||
// flash client will close connection when got this packet,
|
||||
// for the publish queue may contains packets.
|
||||
SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_finish();
|
||||
pkt->data->set("code", SrsAmf0Any::number(ERROR_SUCCESS));
|
||||
pkt->data->set("start_time", SrsAmf0Any::number(start_time));
|
||||
pkt->data->set("end_time", SrsAmf0Any::number(end_time));
|
||||
pkt->data->set("play_kbps", SrsAmf0Any::number(play_sample.kbps));
|
||||
|
@ -445,7 +449,7 @@ int SrsBandwidth::finial(SrsBandwidthSample& play_sample, SrsBandwidthSample& pu
|
|||
bool is_flash = (_req->swfUrl != "");
|
||||
if (!is_flash) {
|
||||
// ignore any error.
|
||||
_srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_flash_final);
|
||||
_srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_final);
|
||||
srs_info("BW check recv flash final response.");
|
||||
}
|
||||
|
||||
|
|
|
@ -97,11 +97,10 @@ int SrsForwarder::on_publish(SrsRequest* req, std::string forward_server)
|
|||
}
|
||||
// discovery vhost
|
||||
std::string vhost = req->vhost;
|
||||
srs_vhost_resolve(vhost, s_port);
|
||||
port = ::atoi(s_port.c_str());
|
||||
|
||||
// generate tcUrl
|
||||
tc_url = srs_generate_tc_url(forward_server, vhost, req->app, s_port);
|
||||
tc_url = srs_generate_tc_url(forward_server, vhost, req->app, s_port, req->param);
|
||||
|
||||
// dead loop check
|
||||
std::string source_ep = "rtmp://";
|
||||
|
|
254
trunk/src/libs/srs_lib_bandwidth.cpp
Normal file
254
trunk/src/libs/srs_lib_bandwidth.cpp
Normal file
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-2014 winlin
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <srs_lib_bandwidth.hpp>
|
||||
|
||||
#include <srs_kernel_error.hpp>
|
||||
#include <srs_protocol_stack.hpp>
|
||||
#include <srs_protocol_rtmp.hpp>
|
||||
#include <srs_core_autofree.hpp>
|
||||
#include <srs_kernel_utility.hpp>
|
||||
|
||||
/**
|
||||
* recv bandwidth helper.
|
||||
*/
|
||||
typedef bool (*_CheckPacketType)(SrsBandwidthPacket* pkt);
|
||||
bool _bandwidth_is_start_play(SrsBandwidthPacket* pkt)
|
||||
{
|
||||
return pkt->is_start_play();
|
||||
}
|
||||
bool _bandwidth_is_stop_play(SrsBandwidthPacket* pkt)
|
||||
{
|
||||
return pkt->is_stop_play();
|
||||
}
|
||||
bool _bandwidth_is_start_publish(SrsBandwidthPacket* pkt)
|
||||
{
|
||||
return pkt->is_start_publish();
|
||||
}
|
||||
bool _bandwidth_is_finish(SrsBandwidthPacket* pkt)
|
||||
{
|
||||
return pkt->is_finish();
|
||||
}
|
||||
int _srs_expect_bandwidth_packet(SrsRtmpClient* rtmp, _CheckPacketType pfn)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
while (true) {
|
||||
SrsMessage* msg = NULL;
|
||||
SrsBandwidthPacket* pkt = NULL;
|
||||
if ((ret = rtmp->expect_message<SrsBandwidthPacket>(&msg, &pkt)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
SrsAutoFree(SrsMessage, msg);
|
||||
SrsAutoFree(SrsBandwidthPacket, pkt);
|
||||
srs_info("get final message success.");
|
||||
|
||||
if (pfn(pkt)) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
SrsBandwidthClient::SrsBandwidthClient()
|
||||
{
|
||||
_rtmp = NULL;
|
||||
}
|
||||
|
||||
SrsBandwidthClient::~SrsBandwidthClient()
|
||||
{
|
||||
}
|
||||
|
||||
int SrsBandwidthClient::initialize(SrsRtmpClient* rtmp)
|
||||
{
|
||||
_rtmp = rtmp;
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
int SrsBandwidthClient::bandwidth_check(
|
||||
char srs_server[128], char srs_primary_authors[128],
|
||||
char srs_id[64], char srs_pid[64], char srs_server_ip[128],
|
||||
int64_t* start_time, int64_t* end_time,
|
||||
int* play_kbps, int* publish_kbps,
|
||||
int* play_bytes, int* publish_bytes,
|
||||
int* play_duration, int* publish_duration
|
||||
) {
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
*start_time = srs_get_system_time_ms();
|
||||
|
||||
// play
|
||||
if ((ret = play_start()) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
if ((ret = play_checking()) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
if ((ret = play_stop()) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// publish
|
||||
if ((ret = publish_start()) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
if ((ret = publish_checking()) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
if ((ret = publish_stop()) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
*end_time = srs_get_system_time_ms();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsBandwidthClient::play_start()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_start_play)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
srs_info("BW check recv play begin request.");
|
||||
|
||||
if (true) {
|
||||
// send start play response to server.
|
||||
SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_starting_play();
|
||||
|
||||
if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
|
||||
srs_error("send bandwidth check start play message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
srs_info("BW check play begin.");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsBandwidthClient::play_checking()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsBandwidthClient::play_stop()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_stop_play)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
srs_info("BW check recv play stop request.");
|
||||
|
||||
if (true) {
|
||||
// send stop play response to server.
|
||||
SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_stop_play();
|
||||
|
||||
if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
|
||||
srs_error("send bandwidth check stop play message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
srs_info("BW check play stop.");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsBandwidthClient::publish_start()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_start_publish)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
srs_info("BW check recv publish begin request.");
|
||||
|
||||
if (true) {
|
||||
// send start publish response to server.
|
||||
SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_starting_publish();
|
||||
|
||||
if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
|
||||
srs_error("send bandwidth check start publish message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
srs_info("BW check publish begin.");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsBandwidthClient::publish_checking()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsBandwidthClient::publish_stop()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_start_publish)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
srs_info("BW check recv publish stop request.");
|
||||
|
||||
if (true) {
|
||||
// send start publish response to server.
|
||||
SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_starting_publish();
|
||||
|
||||
if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
|
||||
srs_error("send bandwidth check stop publish message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
srs_info("BW check publish stop.");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsBandwidthClient::finial()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_finish)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
srs_info("BW check recv finish/report request.");
|
||||
|
||||
if (true) {
|
||||
// send final response to server.
|
||||
SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_final();
|
||||
|
||||
if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
|
||||
srs_error("send bandwidth check final message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
srs_info("BW check final.");
|
||||
|
||||
return ret;
|
||||
}
|
97
trunk/src/libs/srs_lib_bandwidth.hpp
Normal file
97
trunk/src/libs/srs_lib_bandwidth.hpp
Normal file
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-2014 winlin
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SRS_LIB_BANDWIDTH_HPP
|
||||
#define SRS_LIB_BANDWIDTH_HPP
|
||||
|
||||
/*
|
||||
#include <srs_lib_bandwidth.hpp>
|
||||
*/
|
||||
|
||||
#include <srs_core.hpp>
|
||||
|
||||
class SrsRtmpClient;
|
||||
|
||||
/**
|
||||
* bandwith client library for srs-librtmp.
|
||||
*/
|
||||
class SrsBandwidthClient
|
||||
{
|
||||
private:
|
||||
SrsRtmpClient* _rtmp;
|
||||
public:
|
||||
SrsBandwidthClient();
|
||||
virtual ~SrsBandwidthClient();
|
||||
public:
|
||||
/**
|
||||
* initialize the bandwidth check client.
|
||||
*/
|
||||
virtual int initialize(SrsRtmpClient* rtmp);
|
||||
/**
|
||||
* do bandwidth check.
|
||||
*
|
||||
* SRS debug info:
|
||||
* @param srs_server, 128bytes, server info.
|
||||
* @param srs_primary_authors, 128bytes, primary authors.
|
||||
* @param srs_id, 64bytes, debug info, client id in server log.
|
||||
* @param srs_pid, 64bytes, debug info, server pid in log.
|
||||
* @param srs_server_ip, 128bytes, debug info, server ip client connected at.
|
||||
*
|
||||
* bandwidth info:
|
||||
* @param start_time, output the start time, in ms.
|
||||
* @param end_time, output the end time, in ms.
|
||||
* @param play_kbps, output the play/download kbps.
|
||||
* @param publish_kbps, output the publish/upload kbps.
|
||||
* @param play_bytes, output the play/download bytes.
|
||||
* @param publish_bytes, output the publish/upload bytes.
|
||||
* @param play_duration, output the play/download test duration, in ms.
|
||||
* @param publish_duration, output the publish/upload test duration, in ms.
|
||||
*/
|
||||
virtual int bandwidth_check(
|
||||
char srs_server[128], char srs_primary_authors[128],
|
||||
char srs_id[64], char srs_pid[64], char srs_server_ip[128],
|
||||
int64_t* start_time, int64_t* end_time,
|
||||
int* play_kbps, int* publish_kbps,
|
||||
int* play_bytes, int* publish_bytes,
|
||||
int* play_duration, int* publish_duration
|
||||
);
|
||||
private:
|
||||
/**
|
||||
* play check/test, downloading bandwidth kbps.
|
||||
*/
|
||||
virtual int play_start();
|
||||
virtual int play_checking();
|
||||
virtual int play_stop();
|
||||
/**
|
||||
* publish check/test, publishing bandwidth kbps.
|
||||
*/
|
||||
virtual int publish_start();
|
||||
virtual int publish_checking();
|
||||
virtual int publish_stop();
|
||||
/**
|
||||
* report and final packet
|
||||
*/
|
||||
virtual int finial();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -42,6 +42,7 @@ using namespace std;
|
|||
#include <srs_kernel_flv.hpp>
|
||||
#include <srs_kernel_codec.hpp>
|
||||
#include <srs_kernel_file.hpp>
|
||||
#include <srs_lib_bandwidth.hpp>
|
||||
|
||||
// if user want to define log, define the folowing macro.
|
||||
#ifndef SRS_RTMP_USER_DEFINED_LOG
|
||||
|
@ -63,6 +64,7 @@ struct Context
|
|||
std::string vhost;
|
||||
std::string app;
|
||||
std::string stream;
|
||||
std::string param;
|
||||
|
||||
SrsRtmpClient* rtmp;
|
||||
SimpleSocketStream* skt;
|
||||
|
@ -91,39 +93,11 @@ int srs_librtmp_context_parse_uri(Context* context)
|
|||
context->stream = uri.substr(pos + 1);
|
||||
context->tcUrl = uri = uri.substr(0, pos);
|
||||
}
|
||||
// schema
|
||||
if ((pos = uri.find("rtmp://")) != string::npos) {
|
||||
uri = uri.substr(pos + 7);
|
||||
}
|
||||
// host/vhost/port
|
||||
if ((pos = uri.find(":")) != string::npos) {
|
||||
context->vhost = context->host = uri.substr(0, pos);
|
||||
uri = uri.substr(pos + 1);
|
||||
|
||||
if ((pos = uri.find("/")) != string::npos) {
|
||||
context->port = uri.substr(0, pos);
|
||||
uri = uri.substr(pos + 1);
|
||||
}
|
||||
} else {
|
||||
if ((pos = uri.find("/")) != string::npos) {
|
||||
context->vhost = context->host = uri.substr(0, pos);
|
||||
uri = uri.substr(pos + 1);
|
||||
}
|
||||
context->port = RTMP_DEFAULT_PORT;
|
||||
}
|
||||
// app
|
||||
context->app = uri;
|
||||
// query of app
|
||||
if ((pos = uri.find("?")) != string::npos) {
|
||||
context->app = uri.substr(0, pos);
|
||||
string query = uri.substr(pos + 1);
|
||||
if ((pos = query.find("vhost=")) != string::npos) {
|
||||
context->vhost = query.substr(pos + 6);
|
||||
if ((pos = context->vhost.find("&")) != string::npos) {
|
||||
context->vhost = context->vhost.substr(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string schema;
|
||||
srs_discovery_tc_url(context->tcUrl,
|
||||
schema, context->host, context->vhost, context->app, context->port,
|
||||
context->param);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -176,6 +150,18 @@ srs_rtmp_t srs_rtmp_create(const char* url)
|
|||
return context;
|
||||
}
|
||||
|
||||
srs_rtmp_t srs_rtmp_create2(const char* url)
|
||||
{
|
||||
Context* context = new Context();
|
||||
|
||||
// use url as tcUrl.
|
||||
context->url = url;
|
||||
// auto append stream.
|
||||
context->url += "/livestream";
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
void srs_rtmp_destroy(srs_rtmp_t rtmp)
|
||||
{
|
||||
srs_assert(rtmp != NULL);
|
||||
|
@ -263,7 +249,10 @@ int srs_connect_app(srs_rtmp_t rtmp)
|
|||
srs_assert(rtmp != NULL);
|
||||
Context* context = (Context*)rtmp;
|
||||
|
||||
string tcUrl = srs_generate_tc_url(context->ip, context->vhost, context->app, context->port);
|
||||
string tcUrl = srs_generate_tc_url(
|
||||
context->ip, context->vhost, context->app, context->port,
|
||||
context->param
|
||||
);
|
||||
if ((ret = context->rtmp->connect_app(context->app, tcUrl)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -319,6 +308,52 @@ const char* srs_type2string(int type)
|
|||
return unknown;
|
||||
}
|
||||
|
||||
int srs_bandwidth_check(srs_rtmp_t rtmp,
|
||||
char srs_server[128], char srs_primary_authors[128],
|
||||
char srs_id[64], char srs_pid[64], char srs_server_ip[128],
|
||||
int64_t* start_time, int64_t* end_time,
|
||||
int* play_kbps, int* publish_kbps,
|
||||
int* play_bytes, int* publish_bytes,
|
||||
int* play_duration, int* publish_duration
|
||||
) {
|
||||
srs_server[0] = 0;
|
||||
srs_primary_authors[0] = 0;
|
||||
srs_id[0] = 0;
|
||||
srs_pid[0] = 0;
|
||||
srs_server_ip[0] = 0;
|
||||
|
||||
*start_time = 0;
|
||||
*end_time = 0;
|
||||
*play_kbps = 0;
|
||||
*publish_kbps = 0;
|
||||
*play_bytes = 0;
|
||||
*publish_bytes = 0;
|
||||
*play_duration = 0;
|
||||
*publish_duration = 0;
|
||||
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
srs_assert(rtmp != NULL);
|
||||
Context* context = (Context*)rtmp;
|
||||
|
||||
SrsBandwidthClient client;
|
||||
|
||||
if ((ret = client.initialize(context->rtmp)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = client.bandwidth_check(
|
||||
srs_server, srs_primary_authors,
|
||||
srs_id, srs_pid, srs_server_ip,
|
||||
start_time, end_time, play_kbps, publish_kbps,
|
||||
play_bytes, publish_bytes, play_duration, publish_duration)) != ERROR_SUCCESS
|
||||
) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int srs_read_packet(srs_rtmp_t rtmp, int* type, u_int32_t* timestamp, char** data, int* size)
|
||||
{
|
||||
*type = 0;
|
||||
|
|
|
@ -52,6 +52,18 @@ typedef void* srs_rtmp_t;
|
|||
* @return a rtmp handler, or NULL if error occured.
|
||||
*/
|
||||
srs_rtmp_t srs_rtmp_create(const char* url);
|
||||
/**
|
||||
* create rtmp with url, used for connection specified application.
|
||||
* @param url the tcUrl, for exmple:
|
||||
* rtmp://127.0.0.1/live
|
||||
* @remark this is used to create application connection-oriented,
|
||||
* for example, the bandwidth client used this, no stream specified.
|
||||
*/
|
||||
srs_rtmp_t srs_rtmp_create2(const char* url);
|
||||
/**
|
||||
* close and destroy the rtmp stack.
|
||||
* @remark, user should use the rtmp again.
|
||||
*/
|
||||
void srs_rtmp_destroy(srs_rtmp_t rtmp);
|
||||
|
||||
/**
|
||||
|
@ -107,6 +119,35 @@ int srs_play_stream(srs_rtmp_t rtmp);
|
|||
*/
|
||||
int srs_publish_stream(srs_rtmp_t rtmp);
|
||||
|
||||
/**
|
||||
* do bandwidth check with srs server.
|
||||
*
|
||||
* SRS debug info:
|
||||
* @param srs_server, 128bytes, server info.
|
||||
* @param srs_primary_authors, 128bytes, primary authors.
|
||||
* @param srs_id, 64bytes, debug info, client id in server log.
|
||||
* @param srs_pid, 64bytes, debug info, server pid in log.
|
||||
* @param srs_server_ip, 128bytes, debug info, server ip client connected at.
|
||||
*
|
||||
* bandwidth info:
|
||||
* @param start_time, output the start time, in ms.
|
||||
* @param end_time, output the end time, in ms.
|
||||
* @param play_kbps, output the play/download kbps.
|
||||
* @param publish_kbps, output the publish/upload kbps.
|
||||
* @param play_bytes, output the play/download bytes.
|
||||
* @param publish_bytes, output the publish/upload bytes.
|
||||
* @param play_duration, output the play/download test duration, in ms.
|
||||
* @param publish_duration, output the publish/upload test duration, in ms.
|
||||
*/
|
||||
int srs_bandwidth_check(srs_rtmp_t rtmp,
|
||||
char srs_server[128], char srs_primary_authors[128],
|
||||
char srs_id[64], char srs_pid[64], char srs_server_ip[128],
|
||||
int64_t* start_time, int64_t* end_time,
|
||||
int* play_kbps, int* publish_kbps,
|
||||
int* play_bytes, int* publish_bytes,
|
||||
int* play_duration, int* publish_duration
|
||||
);
|
||||
|
||||
/**
|
||||
* E.4.1 FLV Tag, page 75
|
||||
*/
|
||||
|
|
|
@ -95,6 +95,7 @@ SrsRequest* SrsRequest::copy()
|
|||
cp->pageUrl = pageUrl;
|
||||
cp->host = host;
|
||||
cp->port = port;
|
||||
cp->param = param;
|
||||
cp->schema = schema;
|
||||
cp->stream = stream;
|
||||
cp->swfUrl = swfUrl;
|
||||
|
@ -823,7 +824,9 @@ int SrsRtmpServer::connect_app(SrsRequest* req)
|
|||
|
||||
srs_info("get connect app message params success.");
|
||||
|
||||
srs_discovery_tc_url(req->tcUrl, req->schema, req->host, req->vhost, req->app, req->port);
|
||||
srs_discovery_tc_url(req->tcUrl,
|
||||
req->schema, req->host, req->vhost, req->app, req->port,
|
||||
req->param);
|
||||
req->strip();
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -67,10 +67,17 @@ public:
|
|||
public:
|
||||
// discovery from tcUrl and play/publish.
|
||||
std::string schema;
|
||||
// the vhost in tcUrl.
|
||||
std::string vhost;
|
||||
// the host in tcUrl.
|
||||
std::string host;
|
||||
// the port in tcUrl.
|
||||
std::string port;
|
||||
// the app in tcUrl, without param.
|
||||
std::string app;
|
||||
// the param in tcUrl(app).
|
||||
std::string param;
|
||||
// the stream in play/publish
|
||||
std::string stream;
|
||||
// for play live stream,
|
||||
// used to specified the stop when exceed the duration.
|
||||
|
|
|
@ -232,17 +232,16 @@ messages.
|
|||
#define SRS_BW_CHECK_START_PUBLISH "onSrsBandCheckStartPublishBytes"
|
||||
#define SRS_BW_CHECK_STARTING_PUBLISH "onSrsBandCheckStartingPublishBytes"
|
||||
#define SRS_BW_CHECK_STOP_PUBLISH "onSrsBandCheckStopPublishBytes"
|
||||
// @remark, flash never send out this packet, for its queue is full.
|
||||
#define SRS_BW_CHECK_STOPPED_PUBLISH "onSrsBandCheckStoppedPublishBytes"
|
||||
|
||||
// EOF control.
|
||||
// the report packet when check finished.
|
||||
#define SRS_BW_CHECK_FINISHED "onSrsBandCheckFinished"
|
||||
// for flash, it will sendout a final call,
|
||||
// used to confirm got the report.
|
||||
// actually, client send out this packet and close the connection,
|
||||
// so server may cannot got this packet, ignore is ok.
|
||||
#define SRS_BW_CHECK_FLASH_FINAL "finalClientPacket"
|
||||
// @remark, flash never send out this packet, for its queue is full.
|
||||
#define SRS_BW_CHECK_FINAL "finalClientPacket"
|
||||
|
||||
// client only
|
||||
// data packets
|
||||
#define SRS_BW_CHECK_PLAYING "onSrsBandCheckPlaying"
|
||||
#define SRS_BW_CHECK_PUBLISHING "onSrsBandCheckPublishing"
|
||||
|
||||
|
@ -688,7 +687,7 @@ int SrsProtocol::do_decode_message(SrsMessageHeader& header, SrsStream* stream,
|
|||
|| command == SRS_BW_CHECK_STOP_PLAY
|
||||
|| command == SRS_BW_CHECK_STOP_PUBLISH
|
||||
|| command == SRS_BW_CHECK_STOPPED_PUBLISH
|
||||
|| command == SRS_BW_CHECK_FLASH_FINAL)
|
||||
|| command == SRS_BW_CHECK_FINAL)
|
||||
{
|
||||
srs_info("decode the AMF0/AMF3 band width check message.");
|
||||
*ppacket = packet = new SrsBandwidthPacket();
|
||||
|
@ -3270,35 +3269,54 @@ int SrsBandwidthPacket::encode_packet(SrsStream* stream)
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool SrsBandwidthPacket::is_start_play()
|
||||
{
|
||||
return command_name == SRS_BW_CHECK_START_PLAY;
|
||||
}
|
||||
|
||||
bool SrsBandwidthPacket::is_starting_play()
|
||||
{
|
||||
return command_name == SRS_BW_CHECK_STARTING_PLAY;
|
||||
}
|
||||
|
||||
bool SrsBandwidthPacket::is_stop_play()
|
||||
{
|
||||
return command_name == SRS_BW_CHECK_STOP_PLAY;
|
||||
}
|
||||
|
||||
bool SrsBandwidthPacket::is_stopped_play()
|
||||
{
|
||||
return command_name == SRS_BW_CHECK_STOPPED_PLAY;
|
||||
}
|
||||
|
||||
bool SrsBandwidthPacket::is_start_publish()
|
||||
{
|
||||
return command_name == SRS_BW_CHECK_START_PUBLISH;
|
||||
}
|
||||
|
||||
bool SrsBandwidthPacket::is_starting_publish()
|
||||
{
|
||||
return command_name == SRS_BW_CHECK_STARTING_PUBLISH;
|
||||
}
|
||||
|
||||
bool SrsBandwidthPacket::is_stop_publish()
|
||||
{
|
||||
return command_name == SRS_BW_CHECK_STOP_PUBLISH;
|
||||
}
|
||||
|
||||
bool SrsBandwidthPacket::is_stopped_publish()
|
||||
{
|
||||
return command_name == SRS_BW_CHECK_STOPPED_PUBLISH;
|
||||
}
|
||||
|
||||
bool SrsBandwidthPacket::is_flash_final()
|
||||
bool SrsBandwidthPacket::is_finish()
|
||||
{
|
||||
return command_name == SRS_BW_CHECK_FLASH_FINAL;
|
||||
return command_name == SRS_BW_CHECK_FINISHED;
|
||||
}
|
||||
|
||||
SrsBandwidthPacket* SrsBandwidthPacket::create_finish()
|
||||
bool SrsBandwidthPacket::is_final()
|
||||
{
|
||||
SrsBandwidthPacket* pkt = new SrsBandwidthPacket();
|
||||
return pkt->set_command(SRS_BW_CHECK_FINISHED);
|
||||
return command_name == SRS_BW_CHECK_FINAL;
|
||||
}
|
||||
|
||||
SrsBandwidthPacket* SrsBandwidthPacket::create_start_play()
|
||||
|
@ -3307,6 +3325,12 @@ SrsBandwidthPacket* SrsBandwidthPacket::create_start_play()
|
|||
return pkt->set_command(SRS_BW_CHECK_START_PLAY);
|
||||
}
|
||||
|
||||
SrsBandwidthPacket* SrsBandwidthPacket::create_starting_play()
|
||||
{
|
||||
SrsBandwidthPacket* pkt = new SrsBandwidthPacket();
|
||||
return pkt->set_command(SRS_BW_CHECK_STARTING_PLAY);
|
||||
}
|
||||
|
||||
SrsBandwidthPacket* SrsBandwidthPacket::create_playing()
|
||||
{
|
||||
SrsBandwidthPacket* pkt = new SrsBandwidthPacket();
|
||||
|
@ -3325,12 +3349,36 @@ SrsBandwidthPacket* SrsBandwidthPacket::create_start_publish()
|
|||
return pkt->set_command(SRS_BW_CHECK_START_PUBLISH);
|
||||
}
|
||||
|
||||
SrsBandwidthPacket* SrsBandwidthPacket::create_starting_publish()
|
||||
{
|
||||
SrsBandwidthPacket* pkt = new SrsBandwidthPacket();
|
||||
return pkt->set_command(SRS_BW_CHECK_STARTING_PUBLISH);
|
||||
}
|
||||
|
||||
SrsBandwidthPacket* SrsBandwidthPacket::create_publishing()
|
||||
{
|
||||
SrsBandwidthPacket* pkt = new SrsBandwidthPacket();
|
||||
return pkt->set_command(SRS_BW_CHECK_PUBLISHING);
|
||||
}
|
||||
|
||||
SrsBandwidthPacket* SrsBandwidthPacket::create_stop_publish()
|
||||
{
|
||||
SrsBandwidthPacket* pkt = new SrsBandwidthPacket();
|
||||
return pkt->set_command(SRS_BW_CHECK_STOP_PUBLISH);
|
||||
}
|
||||
|
||||
SrsBandwidthPacket* SrsBandwidthPacket::create_finish()
|
||||
{
|
||||
SrsBandwidthPacket* pkt = new SrsBandwidthPacket();
|
||||
return pkt->set_command(SRS_BW_CHECK_FINISHED);
|
||||
}
|
||||
|
||||
SrsBandwidthPacket* SrsBandwidthPacket::create_final()
|
||||
{
|
||||
SrsBandwidthPacket* pkt = new SrsBandwidthPacket();
|
||||
return pkt->set_command(SRS_BW_CHECK_FINAL);
|
||||
}
|
||||
|
||||
SrsBandwidthPacket* SrsBandwidthPacket::set_command(string command)
|
||||
{
|
||||
command_name = command;
|
||||
|
|
|
@ -1230,17 +1230,26 @@ protected:
|
|||
virtual int encode_packet(SrsStream* stream);
|
||||
// help function for bandwidth packet.
|
||||
public:
|
||||
virtual bool is_start_play();
|
||||
virtual bool is_starting_play();
|
||||
virtual bool is_stop_play();
|
||||
virtual bool is_stopped_play();
|
||||
virtual bool is_start_publish();
|
||||
virtual bool is_starting_publish();
|
||||
virtual bool is_stop_publish();
|
||||
virtual bool is_stopped_publish();
|
||||
virtual bool is_flash_final();
|
||||
static SrsBandwidthPacket* create_finish();
|
||||
virtual bool is_finish();
|
||||
virtual bool is_final();
|
||||
static SrsBandwidthPacket* create_start_play();
|
||||
static SrsBandwidthPacket* create_starting_play();
|
||||
static SrsBandwidthPacket* create_playing();
|
||||
static SrsBandwidthPacket* create_stop_play();
|
||||
static SrsBandwidthPacket* create_start_publish();
|
||||
static SrsBandwidthPacket* create_starting_publish();
|
||||
static SrsBandwidthPacket* create_publishing();
|
||||
static SrsBandwidthPacket* create_stop_publish();
|
||||
static SrsBandwidthPacket* create_finish();
|
||||
static SrsBandwidthPacket* create_final();
|
||||
private:
|
||||
virtual SrsBandwidthPacket* set_command(std::string command);
|
||||
};
|
||||
|
|
|
@ -32,7 +32,7 @@ using namespace std;
|
|||
void srs_discovery_tc_url(
|
||||
string tcUrl,
|
||||
string& schema, string& host, string& vhost,
|
||||
string& app, string& port
|
||||
string& app, string& port, std::string& param
|
||||
) {
|
||||
size_t pos = std::string::npos;
|
||||
std::string url = tcUrl;
|
||||
|
@ -58,16 +58,23 @@ void srs_discovery_tc_url(
|
|||
|
||||
app = url;
|
||||
vhost = host;
|
||||
srs_vhost_resolve(vhost, app);
|
||||
srs_vhost_resolve(vhost, app, param);
|
||||
}
|
||||
|
||||
void srs_vhost_resolve(string& vhost, string& app)
|
||||
void srs_vhost_resolve(string& vhost, string& app, string& param)
|
||||
{
|
||||
// get original param
|
||||
size_t pos = 0;
|
||||
if ((pos = app.find("?")) != std::string::npos) {
|
||||
param = app.substr(pos);
|
||||
}
|
||||
|
||||
// filter tcUrl
|
||||
app = srs_string_replace(app, ",", "?");
|
||||
app = srs_string_replace(app, "...", "?");
|
||||
app = srs_string_replace(app, "&&", "?");
|
||||
app = srs_string_replace(app, "=", "?");
|
||||
|
||||
size_t pos = 0;
|
||||
if ((pos = app.find("?")) == std::string::npos) {
|
||||
return;
|
||||
}
|
||||
|
@ -106,7 +113,7 @@ void srs_random_generate(char* bytes, int size)
|
|||
}
|
||||
}
|
||||
|
||||
string srs_generate_tc_url(string ip, string vhost, string app, string port)
|
||||
string srs_generate_tc_url(string ip, string vhost, string app, string port, string param)
|
||||
{
|
||||
string tcUrl = "rtmp://";
|
||||
|
||||
|
@ -123,6 +130,7 @@ string srs_generate_tc_url(string ip, string vhost, string app, string port)
|
|||
|
||||
tcUrl += "/";
|
||||
tcUrl += app;
|
||||
tcUrl += param;
|
||||
|
||||
return tcUrl;
|
||||
}
|
||||
|
|
|
@ -50,20 +50,23 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
* @param app, for example, live
|
||||
* @param port, for example, 19350
|
||||
* default to 1935 if not specified.
|
||||
* param param, for example, vhost=vhost.ossrs.net
|
||||
*/
|
||||
extern void srs_discovery_tc_url(
|
||||
std::string tcUrl,
|
||||
std::string& schema, std::string& host, std::string& vhost,
|
||||
std::string& app, std::string& port
|
||||
std::string& app, std::string& port, std::string& param
|
||||
);
|
||||
|
||||
/**
|
||||
* resolve the vhost in query string
|
||||
* @pram vhost, update the vhost if query contains the vhost.
|
||||
* @param app, may contains the vhost in query string format:
|
||||
* app?vhost=request_vhost
|
||||
* app...vhost...request_vhost
|
||||
* @param param, the query, for example, ?vhost=xxx
|
||||
*/
|
||||
extern void srs_vhost_resolve(std::string& vhost, std::string& app);
|
||||
extern void srs_vhost_resolve(std::string& vhost, std::string& app, std::string& param);
|
||||
|
||||
/**
|
||||
* generate ramdom data for handshake.
|
||||
|
@ -72,12 +75,14 @@ extern void srs_random_generate(char* bytes, int size);
|
|||
|
||||
/**
|
||||
* generate the tcUrl.
|
||||
* @param param, the app parameters in tcUrl. for example, ?key=xxx,vhost=xxx
|
||||
* @return the tcUrl generated from ip/vhost/app/port.
|
||||
* @remark when vhost equals to __defaultVhost__, use ip as vhost.
|
||||
* @remark ignore port if port equals to default port 1935.
|
||||
*/
|
||||
extern std::string srs_generate_tc_url(
|
||||
std::string ip, std::string vhost, std::string app, std::string port
|
||||
std::string ip, std::string vhost, std::string app, std::string port,
|
||||
std::string param
|
||||
);
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,6 +7,8 @@ file
|
|||
libs readonly separator,
|
||||
..\libs\srs_librtmp.hpp,
|
||||
..\libs\srs_librtmp.cpp,
|
||||
..\libs\srs_lib_bandwidth.hpp,
|
||||
..\libs\srs_lib_bandwidth.cpp,
|
||||
..\libs\srs_lib_simple_socket.hpp,
|
||||
..\libs\srs_lib_simple_socket.cpp,
|
||||
core readonly separator,
|
||||
|
@ -121,6 +123,7 @@ file
|
|||
..\utest\srs_utest_protocol.hpp,
|
||||
..\utest\srs_utest_protocol.cpp,
|
||||
research readonly separator,
|
||||
..\..\research\librtmp\srs_bandwidth_check.c,
|
||||
..\..\research\librtmp\srs_detect_rtmp.c,
|
||||
..\..\research\librtmp\srs_flv_injecter.c,
|
||||
..\..\research\librtmp\srs_flv_parser.c,
|
||||
|
|
|
@ -429,27 +429,28 @@ VOID TEST(ProtocolUtilityTest, VhostResolve)
|
|||
{
|
||||
std::string vhost = "vhost";
|
||||
std::string app = "app";
|
||||
srs_vhost_resolve(vhost, app);
|
||||
std::string param;
|
||||
srs_vhost_resolve(vhost, app, param);
|
||||
EXPECT_STREQ("vhost", vhost.c_str());
|
||||
EXPECT_STREQ("app", app.c_str());
|
||||
|
||||
app = "app?vhost=changed";
|
||||
srs_vhost_resolve(vhost, app);
|
||||
srs_vhost_resolve(vhost, app, param);
|
||||
EXPECT_STREQ("changed", vhost.c_str());
|
||||
EXPECT_STREQ("app", app.c_str());
|
||||
|
||||
app = "app?vhost=changed1&&query=true";
|
||||
srs_vhost_resolve(vhost, app);
|
||||
srs_vhost_resolve(vhost, app, param);
|
||||
EXPECT_STREQ("changed1", vhost.c_str());
|
||||
EXPECT_STREQ("app", app.c_str());
|
||||
|
||||
app = "app?other=true&&vhost=changed2&&query=true";
|
||||
srs_vhost_resolve(vhost, app);
|
||||
srs_vhost_resolve(vhost, app, param);
|
||||
EXPECT_STREQ("changed2", vhost.c_str());
|
||||
EXPECT_STREQ("app", app.c_str());
|
||||
|
||||
app = "app...other...true...vhost...changed3...query...true";
|
||||
srs_vhost_resolve(vhost, app);
|
||||
srs_vhost_resolve(vhost, app, param);
|
||||
EXPECT_STREQ("changed3", vhost.c_str());
|
||||
EXPECT_STREQ("app", app.c_str());
|
||||
}
|
||||
|
@ -461,10 +462,10 @@ VOID TEST(ProtocolUtilityTest, DiscoveryTcUrl)
|
|||
{
|
||||
std::string tcUrl;
|
||||
std::string schema; std::string host; std::string vhost;
|
||||
std::string app; std::string port;
|
||||
std::string app; std::string port; std::string param;
|
||||
|
||||
tcUrl = "rtmp://127.0.0.1:1935/live";
|
||||
srs_discovery_tc_url(tcUrl, schema, host, vhost, app, port);
|
||||
srs_discovery_tc_url(tcUrl, schema, host, vhost, app, port, param);
|
||||
EXPECT_STREQ("rtmp", schema.c_str());
|
||||
EXPECT_STREQ("127.0.0.1", host.c_str());
|
||||
EXPECT_STREQ("127.0.0.1", vhost.c_str());
|
||||
|
@ -472,7 +473,7 @@ VOID TEST(ProtocolUtilityTest, DiscoveryTcUrl)
|
|||
EXPECT_STREQ("1935", port.c_str());
|
||||
|
||||
tcUrl = "rtmp://127.0.0.1:19351/live";
|
||||
srs_discovery_tc_url(tcUrl, schema, host, vhost, app, port);
|
||||
srs_discovery_tc_url(tcUrl, schema, host, vhost, app, port, param);
|
||||
EXPECT_STREQ("rtmp", schema.c_str());
|
||||
EXPECT_STREQ("127.0.0.1", host.c_str());
|
||||
EXPECT_STREQ("127.0.0.1", vhost.c_str());
|
||||
|
@ -480,7 +481,7 @@ VOID TEST(ProtocolUtilityTest, DiscoveryTcUrl)
|
|||
EXPECT_STREQ("19351", port.c_str());
|
||||
|
||||
tcUrl = "rtmp://127.0.0.1:19351/live?vhost=demo";
|
||||
srs_discovery_tc_url(tcUrl, schema, host, vhost, app, port);
|
||||
srs_discovery_tc_url(tcUrl, schema, host, vhost, app, port, param);
|
||||
EXPECT_STREQ("rtmp", schema.c_str());
|
||||
EXPECT_STREQ("127.0.0.1", host.c_str());
|
||||
EXPECT_STREQ("demo", vhost.c_str());
|
||||
|
@ -488,7 +489,7 @@ VOID TEST(ProtocolUtilityTest, DiscoveryTcUrl)
|
|||
EXPECT_STREQ("19351", port.c_str());
|
||||
|
||||
tcUrl = "rtmp://127.0.0.1:19351/live/show?vhost=demo";
|
||||
srs_discovery_tc_url(tcUrl, schema, host, vhost, app, port);
|
||||
srs_discovery_tc_url(tcUrl, schema, host, vhost, app, port, param);
|
||||
EXPECT_STREQ("rtmp", schema.c_str());
|
||||
EXPECT_STREQ("127.0.0.1", host.c_str());
|
||||
EXPECT_STREQ("demo", vhost.c_str());
|
||||
|
@ -501,18 +502,18 @@ VOID TEST(ProtocolUtilityTest, DiscoveryTcUrl)
|
|||
*/
|
||||
VOID TEST(ProtocolUtilityTest, GenerateTcUrl)
|
||||
{
|
||||
string ip; string vhost; string app; string port; string tcUrl;
|
||||
string ip; string vhost; string app; string port; string tcUrl; string param;
|
||||
|
||||
ip = "127.0.0.1"; vhost = "__defaultVhost__"; app = "live"; port = "1935";
|
||||
tcUrl = srs_generate_tc_url(ip, vhost, app, port);
|
||||
tcUrl = srs_generate_tc_url(ip, vhost, app, port, param);
|
||||
EXPECT_STREQ("rtmp://127.0.0.1/live", tcUrl.c_str());
|
||||
|
||||
ip = "127.0.0.1"; vhost = "demo"; app = "live"; port = "1935";
|
||||
tcUrl = srs_generate_tc_url(ip, vhost, app, port);
|
||||
tcUrl = srs_generate_tc_url(ip, vhost, app, port, param);
|
||||
EXPECT_STREQ("rtmp://demo/live", tcUrl.c_str());
|
||||
|
||||
ip = "127.0.0.1"; vhost = "demo"; app = "live"; port = "19351";
|
||||
tcUrl = srs_generate_tc_url(ip, vhost, app, port);
|
||||
tcUrl = srs_generate_tc_url(ip, vhost, app, port, param);
|
||||
EXPECT_STREQ("rtmp://demo:19351/live", tcUrl.c_str());
|
||||
}
|
||||
|
||||
|
@ -5375,10 +5376,11 @@ VOID TEST(ProtocolStackTest, ProtocolExcpectMessage)
|
|||
VOID TEST(ProtocolRTMPTest, RTMPRequest)
|
||||
{
|
||||
SrsRequest req;
|
||||
std::string param;
|
||||
|
||||
req.stream = "livestream";
|
||||
srs_discovery_tc_url("rtmp://std.ossrs.net/live",
|
||||
req.schema, req.host, req.vhost, req.app, req.port);
|
||||
req.schema, req.host, req.vhost, req.app, req.port, param);
|
||||
req.strip();
|
||||
EXPECT_STREQ("rtmp", req.schema.c_str());
|
||||
EXPECT_STREQ("std.ossrs.net", req.host.c_str());
|
||||
|
@ -5388,7 +5390,7 @@ VOID TEST(ProtocolRTMPTest, RTMPRequest)
|
|||
|
||||
req.stream = "livestream";
|
||||
srs_discovery_tc_url("rtmp://s td.os srs.n et/li v e",
|
||||
req.schema, req.host, req.vhost, req.app, req.port);
|
||||
req.schema, req.host, req.vhost, req.app, req.port, param);
|
||||
req.strip();
|
||||
EXPECT_STREQ("rtmp", req.schema.c_str());
|
||||
EXPECT_STREQ("std.ossrs.net", req.host.c_str());
|
||||
|
@ -5398,7 +5400,7 @@ VOID TEST(ProtocolRTMPTest, RTMPRequest)
|
|||
|
||||
req.stream = "livestream";
|
||||
srs_discovery_tc_url("rtmp://s\ntd.o\rssrs.ne\nt/li\nve",
|
||||
req.schema, req.host, req.vhost, req.app, req.port);
|
||||
req.schema, req.host, req.vhost, req.app, req.port, param);
|
||||
req.strip();
|
||||
EXPECT_STREQ("rtmp", req.schema.c_str());
|
||||
EXPECT_STREQ("std.ossrs.net", req.host.c_str());
|
||||
|
@ -5408,7 +5410,7 @@ VOID TEST(ProtocolRTMPTest, RTMPRequest)
|
|||
|
||||
req.stream = "livestream";
|
||||
srs_discovery_tc_url("rtmp://std.ossrs.net/live ",
|
||||
req.schema, req.host, req.vhost, req.app, req.port);
|
||||
req.schema, req.host, req.vhost, req.app, req.port, param);
|
||||
req.strip();
|
||||
EXPECT_STREQ("rtmp", req.schema.c_str());
|
||||
EXPECT_STREQ("std.ossrs.net", req.host.c_str());
|
||||
|
|
Loading…
Reference in a new issue