1、ws-flv直播支持客户端主动关闭请求:#430

2、兼容CONTINUATION类型的websocket包
3、修复websocket客户端在处理Content-Length时的相关bug
This commit is contained in:
xiongziliang
2020-08-08 12:17:06 +08:00
parent e7e8969b4f
commit 2fd567b8b0
5 changed files with 149 additions and 61 deletions

View File

@@ -78,7 +78,6 @@ public:
}
};
/**
* 通过该模板类可以透明化WebSocket协议
* 用户只要实现WebSock协议下的具体业务协议譬如基于WebSocket协议的Rtmp协议等
@@ -107,8 +106,9 @@ public:
void attachServer(const TcpServer &server) override{
HttpSessionType::attachServer(server);
_weakServer = const_cast<TcpServer &>(server).shared_from_this();
_weak_server = const_cast<TcpServer &>(server).shared_from_this();
}
protected:
/**
* websocket客户端连接上事件
@@ -122,7 +122,7 @@ protected:
//此url不允许创建websocket连接
return false;
}
auto strongServer = _weakServer.lock();
auto strongServer = _weak_server.lock();
if(strongServer){
_session->attachServer(*strongServer);
}
@@ -145,24 +145,20 @@ protected:
//允许websocket客户端
return true;
}
/**
* 开始收到一个webSocket数据包
* @param packet
*/
void onWebSocketDecodeHeader(const WebSocketHeader &packet) override{
//新包,原来的包残余数据清空掉
_remian_data.clear();
_payload_section.clear();
}
/**
* 收到websocket数据包负载
* @param packet
* @param ptr
* @param len
* @param recved
*/
void onWebSocketDecodePayload(const WebSocketHeader &packet,const uint8_t *ptr,uint64_t len,uint64_t recved) override {
_remian_data.append((char *)ptr,len);
_payload_section.append((char *)ptr,len);
}
/**
@@ -178,39 +174,59 @@ protected:
case WebSocketHeader::CLOSE:{
HttpSessionType::encode(header,nullptr);
HttpSessionType::shutdown(SockException(Err_shutdown, "recv close request from client"));
}
break;
}
case WebSocketHeader::PING:{
header._opcode = WebSocketHeader::PONG;
HttpSessionType::encode(header,std::make_shared<BufferString>(_remian_data));
}
HttpSessionType::encode(header,std::make_shared<BufferString>(_payload_section));
break;
case WebSocketHeader::CONTINUATION:{
}
break;
case WebSocketHeader::CONTINUATION:
case WebSocketHeader::TEXT:
case WebSocketHeader::BINARY:{
_session->onRecv(std::make_shared<BufferString>(_remian_data));
if (!header._fin) {
//还有后续分片数据, 我们先缓存数据,所有分片收集完成才一次性输出
_payload_cache.append(std::move(_payload_section));
if (_payload_cache.size() < MAX_WS_PACKET) {
//还有内存容量缓存分片数据
break;
}
//分片缓存太大,需要清空
}
//最后一个包
if (_payload_cache.empty()) {
//这个包是唯一个分片
_session->onRecv(std::make_shared<WebSocketBuffer>(header._opcode, header._fin, std::move(_payload_section)));
break;
}
//这个包由多个分片组成
_payload_cache.append(std::move(_payload_section));
_session->onRecv(std::make_shared<WebSocketBuffer>(header._opcode, header._fin, std::move(_payload_cache)));
_payload_cache.clear();
break;
}
break;
default:
break;
default: break;
}
_remian_data.clear();
_payload_section.clear();
header._mask_flag = flag;
}
/**
* 发送数据进行websocket协议打包后回调
* @param buffer
* 发送数据进行websocket协议打包后回调
*/
void onWebSocketEncodeData(const Buffer::Ptr &buffer) override{
HttpSessionType::send(buffer);
}
private:
string _remian_data;
weak_ptr<TcpServer> _weakServer;
string _payload_cache;
string _payload_section;
weak_ptr<TcpServer> _weak_server;
TcpSession::Ptr _session;
Creator _creator;
};