Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
Z
ZLMediaKit
概览
Overview
Details
Activity
Cycle Analytics
版本库
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
问题
0
Issues
0
列表
Board
标记
里程碑
合并请求
0
Merge Requests
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
Snippets
成员
Collapse sidebar
Close sidebar
活动
图像
聊天
创建新问题
作业
提交
Issue Boards
Open sidebar
张翔宇
ZLMediaKit
Commits
551b9a43
Commit
551b9a43
authored
7 years ago
by
xiongziliang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
shell登录鉴权改成广播方式
删除rtsp/rtmp shell命令,添加media命令 加载配置文件后发送广播
parent
3c40f171
隐藏空白字符变更
内嵌
并排
正在显示
8 个修改的文件
包含
190 行增加
和
91 行删除
+190
-91
src/Common/config.cpp
+18
-5
src/Common/config.h
+17
-1
src/Device/PlayerProxy.cpp
+13
-0
src/Device/PlayerProxy.h
+2
-2
src/Shell/ShellCMD.cpp
+75
-37
src/Shell/ShellSession.cpp
+48
-31
src/Shell/ShellSession.h
+1
-7
tests/test_server.cpp
+16
-8
没有找到文件。
src/Common/config.cpp
查看文件 @
551b9a43
...
...
@@ -24,6 +24,7 @@
* SOFTWARE.
*/
#include <Util/NoticeCenter.h>
#include "Common/config.h"
#include "Util/util.h"
#include "Util/onceToken.h"
...
...
@@ -33,12 +34,20 @@ using namespace ZL::Network;
namespace
Config
{
void
loadIniConfig
(){
auto
&
ini
=
ZL
::
Util
::
mINI
::
Instance
();
bool
loadIniConfig
(
const
char
*
ini_path
){
string
ini
;
if
(
ini_path
){
ini
=
ini_path
;
}
else
{
ini
=
exePath
()
+
".ini"
;
}
try
{
ini
.
parseFile
(
exePath
()
+
".ini"
);
mINI
::
Instance
().
parseFile
(
ini
);
NoticeCenter
::
Instance
().
emitEvent
(
Broadcast
::
kBroadcastUpdateConfig
);
return
true
;
}
catch
(
std
::
exception
&
ex
)
{
ini
.
dumpFile
(
exePath
()
+
".ini"
);
mINI
::
Instance
().
dumpFile
(
ini
);
return
false
;
}
}
////////////广播名称///////////
...
...
@@ -51,7 +60,11 @@ const char kBroadcastOnRtspAuth[] = "kBroadcastOnRtspAuth";
const
char
kBroadcastMediaPlayed
[]
=
"kBroadcastMediaPlayed"
;
const
char
kBroadcastRtmpPublish
[]
=
"kBroadcastRtmpPublish"
;
const
char
kBroadcastFlowReport
[]
=
"kBroadcastFlowReport"
;
const
char
kFlowThreshold
[]
=
"Broadcast.flowThreshold"
;
const
char
kBroadcastUpdateConfig
[]
=
"kBroadcastUpdateConfig"
;
const
char
kBroadcastShellLogin
[]
=
"kBroadcastShellLogin"
;
const
char
kFlowThreshold
[]
=
"broadcast.flowThreshold"
;
onceToken
token
([](){
mINI
::
Instance
()[
kFlowThreshold
]
=
1024
;
},
nullptr
);
...
...
This diff is collapsed.
Click to expand it.
src/Common/config.h
查看文件 @
551b9a43
...
...
@@ -29,13 +29,19 @@
#define COMMON_CONFIG_H
#include "Util/mini.h"
#include "Util/onceToken.h"
#include <functional>
using
namespace
std
;
using
namespace
ZL
::
Util
;
namespace
Config
{
void
loadIniConfig
();
//加载配置文件,如果配置文件不存在,那么会导出默认配置并生成配置文件
//加载配置文件成功后会触发kBroadcastUpdateConfig广播
//如果指定的文件名(ini_path)为空,那么会加载默认配置文件
//默认配置文件名为 /path/to/your/exe.ini
//加载配置文件成功后返回true,否则返回false
bool
loadIniConfig
(
const
char
*
ini_path
=
nullptr
);
////////////TCP最大连接数///////////
#define MAX_TCP_SESSION 100000
////////////其他宏定义///////////
...
...
@@ -96,12 +102,22 @@ extern const char kBroadcastRtmpPublish[];
extern
const
char
kBroadcastMediaPlayed
[];
#define BroadcastMediaPlayedArgs const MediaInfo &args,const Broadcast::AuthInvoker &invoker
//shell登录鉴权
extern
const
char
kBroadcastShellLogin
[];
#define BroadcastShellLoginArgs const string &user_name,const string &passwd,const Broadcast::AuthInvoker &invoker
//停止rtsp/rtmp/http-flv会话后流量汇报事件广播
extern
const
char
kBroadcastFlowReport
[];
#define BroadcastFlowReportArgs const MediaInfo &args,const uint64_t &totalBytes
//流量汇报事件流量阈值,单位KB,默认1MB
extern
const
char
kFlowThreshold
[];
//更新配置文件事件广播,执行loadIniConfig函数加载配置文件成功后会触发该广播
extern
const
char
kBroadcastUpdateConfig
[];
#define BroadcastUpdateConfigArgs void
#define ReloadConfigTag ((void *)(0xFF))
}
//namespace Broadcast
////////////HTTP配置///////////
...
...
This diff is collapsed.
Click to expand it.
src/Device/PlayerProxy.cpp
查看文件 @
551b9a43
...
...
@@ -131,6 +131,7 @@ void PlayerProxy::initMedia() {
return
;
}
m_pChn
.
reset
(
new
DevChannel
(
m_strVhost
.
data
(),
m_strApp
.
data
(),
m_strSrc
.
data
(),
getDuration
(),
m_bEnableHls
,
m_bEnableMp4
));
m_pChn
->
setListener
(
shared_from_this
());
if
(
containVideo
())
{
VideoInfo
info
;
info
.
iFrameRate
=
getVideoFps
();
...
...
@@ -146,6 +147,18 @@ void PlayerProxy::initMedia() {
m_pChn
->
initAudio
(
info
);
}
}
bool
PlayerProxy
::
shutDown
()
{
//通知其停止推流
weak_ptr
<
PlayerProxy
>
weakSlef
=
dynamic_pointer_cast
<
PlayerProxy
>
(
shared_from_this
());
ASYNC_TRACE
([
weakSlef
](){
auto
stronSelf
=
weakSlef
.
lock
();
if
(
stronSelf
){
stronSelf
->
m_pChn
.
reset
();
stronSelf
->
teardown
();
}
});
return
true
;
}
}
/* namespace Player */
...
...
This diff is collapsed.
Click to expand it.
src/Device/PlayerProxy.h
查看文件 @
551b9a43
...
...
@@ -38,7 +38,7 @@ using namespace ZL::Player;
namespace
ZL
{
namespace
DEV
{
class
PlayerProxy
:
public
MediaPlayer
,
public
std
::
enable_shared_from_this
<
PlayerProxy
>
{
class
PlayerProxy
:
public
MediaPlayer
,
public
std
::
enable_shared_from_this
<
PlayerProxy
>
,
public
MediaSourceEvent
{
public
:
typedef
std
::
shared_ptr
<
PlayerProxy
>
Ptr
;
...
...
@@ -54,7 +54,7 @@ public:
virtual
~
PlayerProxy
();
void
play
(
const
char
*
strUrl
)
override
;
bool
shutDown
()
override
;
private
:
bool
m_bEnableHls
;
bool
m_bEnableMp4
;
...
...
This diff is collapsed.
Click to expand it.
src/Shell/ShellCMD.cpp
查看文件 @
551b9a43
...
...
@@ -3,56 +3,94 @@
//
#include "Util/CMD.h"
#include "Rtsp/RtspMediaSource.h"
#include "Rtmp/RtmpMediaSource.h"
#include "Common/MediaSource.h"
using
namespace
ZL
::
Util
;
using
namespace
ZL
::
Rtsp
;
using
namespace
ZL
::
Rtmp
;
using
namespace
ZL
::
Media
;
namespace
ZL
{
namespace
Shell
{
class
CMD_rtsp
:
public
CMD
{
public
:
CMD_rtsp
(){
_parser
.
reset
(
new
OptionParser
(
nullptr
));
(
*
_parser
)
<<
Option
(
'l'
,
"list"
,
Option
::
ArgNone
,
nullptr
,
false
,
"list all media source of rtsp"
,
[](
const
std
::
shared_ptr
<
ostream
>
&
stream
,
const
string
&
arg
)
{
// auto mediaSet = RtspMediaSource::getMediaSet();
// for (auto &src : mediaSet) {
// (*stream) << "\t" << src << "\r\n";
// }
return
false
;
});
}
virtual
~
CMD_rtsp
()
{}
const
char
*
description
()
const
override
{
return
"查看rtsp服务器相关信息."
;
}
};
class
CMD_rtmp
:
public
CMD
{
class
CMD_media
:
public
CMD
{
public
:
CMD_rtmp
(){
_parser
.
reset
(
new
OptionParser
(
nullptr
));
(
*
_parser
)
<<
Option
(
'l'
,
"list"
,
Option
::
ArgNone
,
nullptr
,
false
,
"list all media source of rtmp"
,
[](
const
std
::
shared_ptr
<
ostream
>
&
stream
,
const
string
&
arg
)
{
// auto mediaSet = RtmpMediaSource::getMediaSet();
// for (auto &src : mediaSet) {
// (*stream) << "\t" << src << "\r\n";
// }
return
false
;
});
CMD_media
(){
_parser
.
reset
(
new
OptionParser
([](
const
std
::
shared_ptr
<
ostream
>
&
stream
,
mINI
&
ini
){
MediaSource
::
for_each_media
([
&
](
const
string
&
schema
,
const
string
&
vhost
,
const
string
&
app
,
const
string
&
streamid
,
const
MediaSource
::
Ptr
&
media
){
if
(
!
ini
[
"schema"
].
empty
()
&&
ini
[
"schema"
]
!=
schema
){
//筛选协议不匹配
return
;
}
if
(
!
ini
[
"vhost"
].
empty
()
&&
ini
[
"vhost"
]
!=
vhost
){
//筛选虚拟主机不匹配
return
;
}
if
(
!
ini
[
"app"
].
empty
()
&&
ini
[
"app"
]
!=
app
){
//筛选应用名不匹配
return
;
}
if
(
!
ini
[
"stream"
].
empty
()
&&
ini
[
"stream"
]
!=
streamid
){
//流id不匹配
return
;
}
if
(
ini
.
find
(
"list"
)
!=
ini
.
end
()){
//列出源
(
*
stream
)
<<
"
\t
"
<<
schema
<<
"/"
<<
vhost
<<
"/"
<<
app
<<
"/"
<<
streamid
<<
"
\r\n
"
;
return
;
}
if
(
ini
.
find
(
"kick"
)
!=
ini
.
end
()){
//踢出源
do
{
if
(
!
media
)
{
break
;
}
if
(
!
media
->
shutDown
())
{
break
;
}
(
*
stream
)
<<
"
\t
踢出成功:"
<<
schema
<<
"/"
<<
vhost
<<
"/"
<<
app
<<
"/"
<<
streamid
<<
"
\r\n
"
;
return
;
}
while
(
0
);
(
*
stream
)
<<
"
\t
踢出失败:"
<<
schema
<<
"/"
<<
vhost
<<
"/"
<<
app
<<
"/"
<<
streamid
<<
"
\r\n
"
;
return
;
}
});
}));
(
*
_parser
)
<<
Option
(
'k'
,
"kick"
,
Option
::
ArgNone
,
nullptr
,
false
,
"踢出媒体源"
,
nullptr
);
(
*
_parser
)
<<
Option
(
'l'
,
"list"
,
Option
::
ArgNone
,
nullptr
,
false
,
"列出媒体源"
,
nullptr
);
(
*
_parser
)
<<
Option
(
'S'
,
"schema"
,
Option
::
ArgRequired
,
nullptr
,
false
,
"协议筛选"
,
nullptr
);
(
*
_parser
)
<<
Option
(
'v'
,
"vhost"
,
Option
::
ArgRequired
,
nullptr
,
false
,
"虚拟主机筛选"
,
nullptr
);
(
*
_parser
)
<<
Option
(
'a'
,
"app"
,
Option
::
ArgRequired
,
nullptr
,
false
,
"应用名筛选"
,
nullptr
);
(
*
_parser
)
<<
Option
(
's'
,
"stream"
,
Option
::
ArgRequired
,
nullptr
,
false
,
"流id筛选"
,
nullptr
);
}
virtual
~
CMD_
rtmp
()
{}
virtual
~
CMD_
media
()
{}
const
char
*
description
()
const
override
{
return
"
查看rtmp服务器相关信息
."
;
return
"
媒体源相关操作
."
;
}
};
static
onceToken
s_token
([]()
{
REGIST_CMD
(
rtmp
);
REGIST_CMD
(
rtsp
);
REGIST_CMD
(
media
);
},
nullptr
);
...
...
This diff is collapsed.
Click to expand it.
src/Shell/ShellSession.cpp
查看文件 @
551b9a43
...
...
@@ -28,14 +28,14 @@
#include "Common/config.h"
#include "Util/CMD.h"
#include "Util/onceToken.h"
#include "Util/NoticeCenter.h"
using
namespace
Config
;
using
namespace
ZL
::
Util
;
namespace
ZL
{
namespace
Shell
{
unordered_map
<
string
,
string
>
ShellSession
::
g_mapUser
;
ShellSession
::
ShellSession
(
const
std
::
shared_ptr
<
ThreadPool
>
&
_th
,
const
Socket
::
Ptr
&
_sock
)
:
TcpLimitedSession
(
_th
,
_sock
)
{
...
...
@@ -82,8 +82,9 @@ void ShellSession::onManager() {
}
inline
bool
ShellSession
::
onCommandLine
(
const
string
&
line
)
{
if
(
m_requestCB
)
{
bool
ret
=
m_requestCB
(
line
);
auto
loginInterceptor
=
m_loginInterceptor
;
if
(
loginInterceptor
)
{
bool
ret
=
loginInterceptor
(
line
);
return
ret
;
}
try
{
...
...
@@ -103,30 +104,55 @@ inline bool ShellSession::onCommandLine(const string& line) {
inline
void
ShellSession
::
pleaseInputUser
()
{
send
(
"
\033
[0m"
);
send
(
StrPrinter
<<
SERVER_NAME
<<
" login: "
<<
endl
);
m_
requestCB
=
[
this
](
const
string
&
lin
e
)
{
m_strUserName
=
lin
e
;
m_
loginInterceptor
=
[
this
](
const
string
&
user_nam
e
)
{
m_strUserName
=
user_nam
e
;
pleaseInputPasswd
();
return
true
;
};
}
inline
void
ShellSession
::
pleaseInputPasswd
()
{
send
(
"Password:
\033
[8m"
);
m_requestCB
=
[
this
](
const
string
&
passwd
)
{
if
(
!
onAuth
(
m_strUserName
,
passwd
))
{
send
(
StrPrinter
<<
"
\033
[0mPermission denied,"
<<
" please try again.
\r\n
"
<<
m_strUserName
<<
"@"
<<
SERVER_NAME
<<
"'s password:
\033
[8m"
<<
endl
);
return
true
;
}
send
(
"
\033
[0m"
);
send
(
"-----------------------------------------
\r\n
"
);
send
(
StrPrinter
<<
"欢迎来到"
<<
SERVER_NAME
<<
", 你可输入
\"
help
\"
查看帮助.
\r\n
"
<<
endl
);
send
(
"-----------------------------------------
\r\n
"
);
printShellPrefix
();
m_requestCB
=
nullptr
;
m_loginInterceptor
=
[
this
](
const
string
&
passwd
)
{
auto
onAuth
=
[
this
](
const
string
&
errMessage
){
if
(
!
errMessage
.
empty
()){
//鉴权失败
send
(
StrPrinter
<<
"
\033
[0mAuth failed("
<<
errMessage
<<
"), please try again.
\r\n
"
<<
m_strUserName
<<
"@"
<<
SERVER_NAME
<<
"'s password:
\033
[8m"
<<
endl
);
return
;
}
send
(
"
\033
[0m"
);
send
(
"-----------------------------------------
\r\n
"
);
send
(
StrPrinter
<<
"欢迎来到"
<<
SERVER_NAME
<<
", 你可输入
\"
help
\"
查看帮助.
\r\n
"
<<
endl
);
send
(
"-----------------------------------------
\r\n
"
);
printShellPrefix
();
m_loginInterceptor
=
nullptr
;
};
weak_ptr
<
ShellSession
>
weakSelf
=
dynamic_pointer_cast
<
ShellSession
>
(
shared_from_this
());
Broadcast
::
AuthInvoker
invoker
=
[
weakSelf
,
onAuth
](
const
string
&
errMessage
){
auto
strongSelf
=
weakSelf
.
lock
();
if
(
!
strongSelf
){
return
;
}
strongSelf
->
async
([
errMessage
,
weakSelf
,
onAuth
](){
auto
strongSelf
=
weakSelf
.
lock
();
if
(
!
strongSelf
){
return
;
}
onAuth
(
errMessage
);
});
};
auto
flag
=
NoticeCenter
::
Instance
().
emitEvent
(
Broadcast
::
kBroadcastShellLogin
,
m_strUserName
,
passwd
,
invoker
);
if
(
!
flag
){
//如果无人监听shell登录事件,那么默认shell无法登录
onAuth
(
"please listen kBroadcastShellLogin event"
);
}
return
true
;
};
}
...
...
@@ -135,14 +161,5 @@ inline void ShellSession::printShellPrefix() {
send
(
StrPrinter
<<
m_strUserName
<<
"@"
<<
SERVER_NAME
<<
"# "
<<
endl
);
}
inline
bool
ShellSession
::
onAuth
(
const
string
&
user
,
const
string
&
pwd
)
{
auto
it
=
g_mapUser
.
find
(
user
);
if
(
it
==
g_mapUser
.
end
())
{
//WarnL << user << " " << pwd;
return
false
;
}
return
it
->
second
==
pwd
;
}
}
/* namespace Shell */
}
/* namespace ZL */
This diff is collapsed.
Click to expand it.
src/Shell/ShellSession.h
查看文件 @
551b9a43
...
...
@@ -48,22 +48,16 @@ public:
void
onError
(
const
SockException
&
err
)
override
{};
void
onManager
()
override
;
static
void
addUser
(
const
string
&
userName
,
const
string
&
userPwd
){
g_mapUser
[
userName
]
=
userPwd
;
}
private
:
inline
bool
onCommandLine
(
const
string
&
);
inline
bool
onAuth
(
const
string
&
user
,
const
string
&
pwd
);
inline
void
pleaseInputUser
();
inline
void
pleaseInputPasswd
();
inline
void
printShellPrefix
();
function
<
bool
(
const
string
&
)
>
m_
requestCB
;
function
<
bool
(
const
string
&
)
>
m_
loginInterceptor
;
string
m_strRecvBuf
;
Ticker
m_beatTicker
;
string
m_strUserName
;
static
unordered_map
<
string
,
string
>
g_mapUser
;
};
}
/* namespace Shell */
...
...
This diff is collapsed.
Click to expand it.
tests/test_server.cpp
查看文件 @
551b9a43
...
...
@@ -112,16 +112,24 @@ static onceToken s_token([](){
NoticeCenter
::
Instance
().
addListener
(
nullptr
,
Config
::
Broadcast
::
kBroadcastRtmpPublish
,[](
BroadcastRtmpPublishArgs
){
InfoL
<<
args
.
m_vhost
<<
" "
<<
args
.
m_app
<<
" "
<<
args
.
m_streamid
<<
" "
<<
args
.
m_param_strs
;
EventPoller
::
Instance
().
async
([
invoker
](){
//
invoker("");//鉴权成功
invoker
(
"this is auth failed message"
);
//鉴权失败
invoker
(
""
);
//鉴权成功
//
invoker("this is auth failed message");//鉴权失败
});
});
NoticeCenter
::
Instance
().
addListener
(
nullptr
,
Config
::
Broadcast
::
kBroadcastMediaPlayed
,[](
BroadcastMediaPlayedArgs
){
InfoL
<<
args
.
m_schema
<<
" "
<<
args
.
m_vhost
<<
" "
<<
args
.
m_app
<<
" "
<<
args
.
m_streamid
<<
" "
<<
args
.
m_param_strs
;
EventPoller
::
Instance
().
async
([
invoker
](){
//invoker("");//鉴权成功
invoker
(
"this is auth failed message"
);
//鉴权失败
invoker
(
""
);
//鉴权成功
//invoker("this is auth failed message");//鉴权失败
});
});
NoticeCenter
::
Instance
().
addListener
(
nullptr
,
Config
::
Broadcast
::
kBroadcastShellLogin
,[](
BroadcastShellLoginArgs
){
InfoL
<<
"shell login:"
<<
user_name
<<
" "
<<
passwd
;
EventPoller
::
Instance
().
async
([
invoker
](){
invoker
(
""
);
//鉴权成功
//invoker("this is auth failed message");//鉴权失败
});
});
...
...
@@ -130,7 +138,9 @@ static onceToken s_token([](){
int
main
(
int
argc
,
char
*
argv
[]){
//设置退出信号处理函数
signal
(
SIGINT
,
[](
int
){
EventPoller
::
Instance
().
shutdown
();});
//设置日志
signal
(
SIGHUP
,
[](
int
){
Config
::
loadIniConfig
();});
//设置日志
Logger
::
Instance
().
add
(
std
::
make_shared
<
ConsoleChannel
>
(
"stdout"
,
LTrace
));
Logger
::
Instance
().
setWriter
(
std
::
make_shared
<
AsyncLogWriter
>
());
//加载配置文件,如果配置文件不存在就创建一个
...
...
@@ -176,10 +186,8 @@ int main(int argc,char *argv[]){
#endif //ENABLE_OPENSSL
//简单的telnet服务器,可用于服务器调试,但是不能使用23端口,否则telnet上了莫名其妙的现象
//测试方法:telnet 127.0.0.1 8023
//输入用户名和密码登录(user:test,pwd:123456),输入help命令查看帮助
//测试方法:telnet 127.0.0.1 9000
TcpServer
<
ShellSession
>::
Ptr
shellSrv
(
new
TcpServer
<
ShellSession
>
());
ShellSession
::
addUser
(
"test"
,
"123456"
);
shellSrv
->
start
(
mINI
::
Instance
()[
Config
::
Shell
::
kPort
]);
//开启rtsp/rtmp/http服务器
TcpServer
<
RtspSession
>::
Ptr
rtspSrv
(
new
TcpServer
<
RtspSession
>
());
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论