初步完成WebSocket

This commit is contained in:
xiongziliang 2018-09-20 18:20:43 +08:00
parent ffb5a22845
commit 4a6019c6fe
3 changed files with 62 additions and 2 deletions

View File

@ -21,6 +21,10 @@ splitPacket:
_remain_data.erase(0, index + 4); _remain_data.erase(0, index + 4);
} }
if(_remain_data.empty()){
return;
}
if(_content_len > 0){ if(_content_len > 0){
//数据按照固定长度content处理 //数据按照固定长度content处理
if(_remain_data.size() < _content_len){ if(_remain_data.size() < _content_len){

View File

@ -40,6 +40,8 @@
#include "Util/onceToken.h" #include "Util/onceToken.h"
#include "Util/mini.h" #include "Util/mini.h"
#include "Util/NoticeCenter.h" #include "Util/NoticeCenter.h"
#include "Util/base64.h"
#include "Util/SHA1.h"
#include "Rtmp/utils.h" #include "Rtmp/utils.h"
using namespace ZL::Util; using namespace ZL::Util;
@ -180,6 +182,23 @@ void HttpSession::onManager() {
shutdown(); shutdown();
} }
} }
inline bool HttpSession::checkWebSocket(){
if(m_parser["Connection"] != "Upgrade" ||
m_parser["Upgrade"] != "websocket" ){
return false;
}
auto Sec_WebSocket_Key = m_parser["Sec-WebSocket-Key"];
auto Sec_WebSocket_Accept = encodeBase64(SHA1::encode_bin(Sec_WebSocket_Key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"));
KeyValue headerOut;
headerOut["Upgrade"] = "websocket";
headerOut["Connection"] = "Upgrade";
headerOut["Sec-WebSocket-Accept"] = Sec_WebSocket_Accept;
sendResponse("101 Switching Protocols",headerOut,"");
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(){
@ -248,16 +267,29 @@ inline bool HttpSession::checkLiveFlvStream(){
return true; return true;
} }
inline bool HttpSession::Handle_Req_GET(int64_t &content_len) { inline bool HttpSession::Handle_Req_GET(int64_t &content_len) {
//先看看是否为WebSocket请求
if(checkWebSocket()){
content_len = -1;
auto parserCopy = m_parser;
m_contentCallBack = [this,parserCopy](const string &data){
onRecvWebSocketData(parserCopy,data);
//m_contentCallBack是可持续的后面还要处理后续数据
return true;
};
return true;
}
//先看看该http事件是否被拦截 //先看看该http事件是否被拦截
if(emitHttpEvent(false)){ if(emitHttpEvent(false)){
return true; return true;
} }
//再看看是否为http-flv直播请求 //再看看是否为http-flv直播请求
if(checkLiveFlvStream()){ if(checkLiveFlvStream()){
return true; return true;
} }
//事件未被拦截则认为是http下载请求
//事件未被拦截则认为是http下载请求
auto fullUrl = string(HTTP_SCHEMA) + "://" + m_parser["Host"] + m_parser.FullUrl(); auto fullUrl = string(HTTP_SCHEMA) + "://" + m_parser["Host"] + m_parser.FullUrl();
m_mediaInfo.parse(fullUrl); m_mediaInfo.parse(fullUrl);

View File

@ -85,7 +85,7 @@ protected:
/** /**
* content * content
* http-flv推流,WebSocket数据 * http-flv推流
* @param header http请求头 * @param header http请求头
* @param content content分片数据 * @param content content分片数据
* @param content_size content大小,0content * @param content_size content大小,0content
@ -95,6 +95,15 @@ protected:
shutdown(); shutdown();
} }
/**
* websocket数据
* @param header http请求头
* @param data websocket数据
*/
virtual void onRecvWebSocketData(const Parser &header,const string &data){
shutdown();
}
private: private:
Parser m_parser; Parser m_parser;
string m_strPath; string m_strPath;
@ -110,6 +119,7 @@ private:
inline bool Handle_Req_GET(int64_t &content_len); inline bool Handle_Req_GET(int64_t &content_len);
inline bool Handle_Req_POST(int64_t &content_len); inline bool Handle_Req_POST(int64_t &content_len);
inline bool checkLiveFlvStream(); inline bool checkLiveFlvStream();
inline bool checkWebSocket();
inline bool emitHttpEvent(bool doInvoke); inline bool emitHttpEvent(bool doInvoke);
inline void urlDecode(Parser &parser); inline void urlDecode(Parser &parser);
inline bool makeMeun(const string &strFullPath,const string &vhost, string &strRet); inline bool makeMeun(const string &strFullPath,const string &vhost, string &strRet);
@ -121,6 +131,20 @@ private:
const string &contentOut); const string &contentOut);
}; };
/**
* WebSocket会话
*/
class EchoWebSocketSession : public HttpSession {
public:
EchoWebSocketSession(const std::shared_ptr<ThreadPool> &pTh, const Socket::Ptr &pSock) : HttpSession(pTh,pSock){};
virtual ~EchoWebSocketSession(){};
protected:
void onRecvWebSocketData(const Parser &header,const string &data) override {
DebugL << "收到websocket数据:" << data;
(*this) << "echo:" << data;
}
};
} /* namespace Http */ } /* namespace Http */
} /* namespace ZL */ } /* namespace ZL */