初步支持websocket-flv直播
This commit is contained in:
parent
7c7b9e560e
commit
8e17300a17
|
|
@ -212,11 +212,12 @@ inline bool HttpSession::checkWebSocket(){
|
||||||
headerOut["Sec-WebSocket-Protocol"] = _parser["Sec-WebSocket-Protocol"];
|
headerOut["Sec-WebSocket-Protocol"] = _parser["Sec-WebSocket-Protocol"];
|
||||||
}
|
}
|
||||||
sendResponse("101 Switching Protocols",headerOut,"");
|
sendResponse("101 Switching Protocols",headerOut,"");
|
||||||
|
checkLiveFlvStream(true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//http-flv 链接格式:http://vhost-url:port/app/streamid.flv?key1=value1&key2=value2
|
//http-flv 链接格式:http://vhost-url:port/app/streamid.flv?key1=value1&key2=value2
|
||||||
//如果url(除去?以及后面的参数)后缀是.flv,那么表明该url是一个http-flv直播。
|
//如果url(除去?以及后面的参数)后缀是.flv,那么表明该url是一个http-flv直播。
|
||||||
inline bool HttpSession::checkLiveFlvStream(){
|
inline bool HttpSession::checkLiveFlvStream(bool over_websocket){
|
||||||
auto pos = strrchr(_parser.Url().data(),'.');
|
auto pos = strrchr(_parser.Url().data(),'.');
|
||||||
if(!pos){
|
if(!pos){
|
||||||
//未找到".flv"后缀
|
//未找到".flv"后缀
|
||||||
|
|
@ -239,7 +240,7 @@ inline bool HttpSession::checkLiveFlvStream(){
|
||||||
bool bClose = (strcasecmp(_parser["Connection"].data(),"close") == 0) || ( ++_iReqCnt > reqCnt);
|
bool bClose = (strcasecmp(_parser["Connection"].data(),"close") == 0) || ( ++_iReqCnt > reqCnt);
|
||||||
|
|
||||||
weak_ptr<HttpSession> weakSelf = dynamic_pointer_cast<HttpSession>(shared_from_this());
|
weak_ptr<HttpSession> weakSelf = dynamic_pointer_cast<HttpSession>(shared_from_this());
|
||||||
MediaSource::findAsync(_mediaInfo,weakSelf.lock(), true,[weakSelf,bClose,this](const MediaSource::Ptr &src){
|
MediaSource::findAsync(_mediaInfo,weakSelf.lock(), true,[weakSelf,bClose,this,over_websocket](const MediaSource::Ptr &src){
|
||||||
auto strongSelf = weakSelf.lock();
|
auto strongSelf = weakSelf.lock();
|
||||||
if(!strongSelf){
|
if(!strongSelf){
|
||||||
//本对象已经销毁
|
//本对象已经销毁
|
||||||
|
|
@ -248,29 +249,35 @@ inline bool HttpSession::checkLiveFlvStream(){
|
||||||
auto rtmp_src = dynamic_pointer_cast<RtmpMediaSource>(src);
|
auto rtmp_src = dynamic_pointer_cast<RtmpMediaSource>(src);
|
||||||
if(!rtmp_src){
|
if(!rtmp_src){
|
||||||
//未找到该流
|
//未找到该流
|
||||||
sendNotFound(bClose);
|
if(!over_websocket){
|
||||||
|
sendNotFound(bClose);
|
||||||
|
}
|
||||||
if(bClose){
|
if(bClose){
|
||||||
shutdown(SockException(Err_shutdown,"flv stream not found"));
|
shutdown(SockException(Err_shutdown,"flv stream not found"));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//找到流了
|
//找到流了
|
||||||
auto onRes = [this,rtmp_src](const string &err){
|
auto onRes = [this,rtmp_src,over_websocket](const string &err){
|
||||||
bool authSuccess = err.empty();
|
bool authSuccess = err.empty();
|
||||||
if(!authSuccess){
|
if(!authSuccess){
|
||||||
sendResponse("401 Unauthorized", makeHttpHeader(true,err.size()),err);
|
if(!over_websocket){
|
||||||
|
sendResponse("401 Unauthorized", makeHttpHeader(true,err.size()),err);
|
||||||
|
}
|
||||||
shutdown(SockException(Err_shutdown,StrPrinter << "401 Unauthorized:" << err));
|
shutdown(SockException(Err_shutdown,StrPrinter << "401 Unauthorized:" << err));
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//找到rtmp源,发送http头,负载后续发送
|
if(!over_websocket) {
|
||||||
sendResponse("200 OK", makeHttpHeader(false,0,get_mime_type(".flv")), "");
|
//找到rtmp源,发送http头,负载后续发送
|
||||||
|
sendResponse("200 OK", makeHttpHeader(false, 0, get_mime_type(".flv")), "");
|
||||||
|
}
|
||||||
|
|
||||||
//开始发送rtmp负载
|
//开始发送rtmp负载
|
||||||
//关闭tcp_nodelay ,优化性能
|
//关闭tcp_nodelay ,优化性能
|
||||||
SockUtil::setNoDelay(_sock->rawFD(),false);
|
SockUtil::setNoDelay(_sock->rawFD(),false);
|
||||||
(*this) << SocketFlags(kSockFlags);
|
(*this) << SocketFlags(kSockFlags);
|
||||||
|
_flv_over_websocket = over_websocket;
|
||||||
try{
|
try{
|
||||||
start(getPoller(),rtmp_src);
|
start(getPoller(),rtmp_src);
|
||||||
}catch (std::exception &ex){
|
}catch (std::exception &ex){
|
||||||
|
|
@ -473,7 +480,7 @@ inline void HttpSession::Handle_Req_GET(int64_t &content_len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//再看看是否为http-flv直播请求
|
//再看看是否为http-flv直播请求
|
||||||
if(checkLiveFlvStream()){
|
if(checkLiveFlvStream(false)){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -936,8 +943,23 @@ inline void HttpSession::sendNotFound(bool bClose) {
|
||||||
|
|
||||||
void HttpSession::onWrite(const Buffer::Ptr &buffer) {
|
void HttpSession::onWrite(const Buffer::Ptr &buffer) {
|
||||||
_ticker.resetTime();
|
_ticker.resetTime();
|
||||||
_ui64TotalBytes += buffer->size();
|
if(!_flv_over_websocket){
|
||||||
send(buffer);
|
_ui64TotalBytes += buffer->size();
|
||||||
|
send(buffer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
WebSocketHeader header;
|
||||||
|
header._fin = true;
|
||||||
|
header._reserved = 0;
|
||||||
|
header._opcode = WebSocketHeader::BINARY;
|
||||||
|
header._mask_flag = false;
|
||||||
|
WebSocketSplitter::encode(header,(uint8_t *)buffer->data(),buffer->size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void HttpSession::onWebSocketEncodeData(const uint8_t *ptr,uint64_t len){
|
||||||
|
_ui64TotalBytes += len;
|
||||||
|
SocketHelper::send((char *)ptr,len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpSession::onDetach() {
|
void HttpSession::onDetach() {
|
||||||
|
|
|
||||||
|
|
@ -102,10 +102,16 @@ protected:
|
||||||
WebSocketSplitter::decode((uint8_t *)data,len);
|
WebSocketSplitter::decode((uint8_t *)data,len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送数据进行websocket协议打包后回调
|
||||||
|
* @param ptr
|
||||||
|
* @param len
|
||||||
|
*/
|
||||||
|
void onWebSocketEncodeData(const uint8_t *ptr,uint64_t len) override;
|
||||||
private:
|
private:
|
||||||
inline void Handle_Req_GET(int64_t &content_len);
|
inline void Handle_Req_GET(int64_t &content_len);
|
||||||
inline void Handle_Req_POST(int64_t &content_len);
|
inline void Handle_Req_POST(int64_t &content_len);
|
||||||
inline bool checkLiveFlvStream();
|
inline bool checkLiveFlvStream(bool over_websocket = false);
|
||||||
inline bool checkWebSocket();
|
inline bool checkWebSocket();
|
||||||
inline bool emitHttpEvent(bool doInvoke);
|
inline bool emitHttpEvent(bool doInvoke);
|
||||||
inline void urlDecode(Parser &parser);
|
inline void urlDecode(Parser &parser);
|
||||||
|
|
@ -148,6 +154,7 @@ private:
|
||||||
MediaInfo _mediaInfo;
|
MediaInfo _mediaInfo;
|
||||||
//处理content数据的callback
|
//处理content数据的callback
|
||||||
function<bool (const char *data,uint64_t len) > _contentCallBack;
|
function<bool (const char *data,uint64_t len) > _contentCallBack;
|
||||||
|
bool _flv_over_websocket = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue