ZLMediaKit/webrtc/WebRtcSession.cpp

95 lines
3.1 KiB
C++
Raw Normal View History

2021-09-08 18:00:55 +08:00
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
#include "WebRtcSession.h"
#include "Util/util.h"
WebRtcSession::WebRtcSession(const Socket::Ptr &sock) : UdpSession(sock) {
socklen_t addr_len = sizeof(_peer_addr);
getpeername(sock->rawFD(), &_peer_addr, &addr_len);
InfoP(this);
}
WebRtcSession::~WebRtcSession() {
InfoP(this);
}
static string getUserName(const Buffer::Ptr &buffer) {
auto buf = buffer->data();
auto len = buffer->size();
if (!RTC::StunPacket::IsStun((const uint8_t *) buf, len)) {
return "";
}
std::unique_ptr<RTC::StunPacket> packet(RTC::StunPacket::Parse((const uint8_t *) buf, len));
if (!packet) {
return "";
}
if (packet->GetClass() != RTC::StunPacket::Class::REQUEST ||
packet->GetMethod() != RTC::StunPacket::Method::BINDING) {
return "";
}
//收到binding request请求
auto vec = split(packet->GetUsername(), ":");
return vec[0];
}
EventPoller::Ptr WebRtcSession::getPoller(const Buffer::Ptr &buffer) {
auto user_name = getUserName(buffer);
if (user_name.empty()) {
return nullptr;
}
2021-09-10 22:31:44 +08:00
auto ret = WebRtcTransportImp::getRtcTransport(user_name, false);
return ret ? ret->getPoller() : nullptr;
}
2021-09-08 18:00:55 +08:00
void WebRtcSession::onRecv(const Buffer::Ptr &buffer) {
2021-09-15 11:50:15 +08:00
try {
onRecv_l(buffer);
} catch (std::exception &ex) {
shutdown(SockException(Err_shutdown, ex.what()));
}
}
2021-09-08 18:00:55 +08:00
2021-09-15 11:50:15 +08:00
void WebRtcSession::onRecv_l(const Buffer::Ptr &buffer) {
if (_find_transport) {
//只允许寻找一次transport
_find_transport = false;
_transport = WebRtcTransportImp::getRtcTransport(getUserName(buffer), true);
CHECK(_transport && _transport->getPoller()->isCurrentThread());
2021-09-10 22:31:44 +08:00
_transport->setSession(shared_from_this());
2021-09-08 18:00:55 +08:00
}
2021-09-10 22:31:44 +08:00
_ticker.resetTime();
2021-09-15 11:50:15 +08:00
CHECK(_transport);
//先增加引用技术防止使用transport时触发onError事件导致对象释放
auto transport = _transport;
transport->inputSockData(buffer->data(), buffer->size(), &_peer_addr);
2021-09-08 18:00:55 +08:00
}
void WebRtcSession::onError(const SockException &err) {
2021-09-10 22:31:44 +08:00
//udp链接超时但是rtc链接不一定超时因为可能存在udp链接迁移的情况
//在udp链接迁移时新的WebRtcSession对象将接管WebRtcTransport对象的生命周期
//本WebRtcSession对象将在超时后自动销毁
WarnP(this) << err.what();
//取消循环引用
_transport = nullptr;
2021-09-08 18:00:55 +08:00
}
void WebRtcSession::onManager() {
2021-09-10 22:31:44 +08:00
GET_CONFIG(float, timeoutSec, RTC::kTimeOutSec);
if (!_transport && _ticker.createdTime() > timeoutSec * 1000) {
shutdown(SockException(Err_timeout, "illegal webrtc connection"));
return;
}
if (_ticker.elapsedTime() > timeoutSec * 1000) {
shutdown(SockException(Err_timeout, "webrtc connection timeout"));
return;
}
2021-09-08 18:00:55 +08:00
}