mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2026-06-14 12:05:58 +08:00
1、ws-flv直播支持客户端主动关闭请求:#430
2、兼容CONTINUATION类型的websocket包 3、修复websocket客户端在处理Content-Length时的相关bug
This commit is contained in:
@@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user