概述
RTC::Transport是mediasoup中的一个重要概念,它用于在mediasoup与客户端之间传输实时音视频数据。
Transport继承着众多的类,主要用于Transport的整体感知
class Transport : public RTC::Producer::Listener,
public RTC::Consumer::Listener,
public RTC::DataProducer::Listener,
public RTC::DataConsumer::Listener,
public RTC::SctpAssociation::Listener,
public RTC::TransportCongestionControlClient::Listener,
public RTC::TransportCongestionControlServer::Listener,
public Channel::ChannelSocket::RequestHandler,
public PayloadChannel::PayloadChannelSocket::RequestHandler,
public PayloadChannel::PayloadChannelSocket::NotificationHandler,
分析Transport的创建流程
在Router层会根据类型来进入分支创建transport,以PlainTransport为例
case Channel::ChannelRequest::MethodId::ROUTER_CREATE_PLAIN_TRANSPORT:
{
std::string transportId;//从上层获取到transport的ID
// This may throw
SetNewTransportIdFromData(request->data, transportId);
auto* plainTransport =
new RTC::PlainTransport(this->shared, transportId, this, request->data);
// Insert into the map.绑定ID与transport的映射
this->mapTransports[transportId] = plainTransport;
MS_DEBUG_DEV("PlainTransport created [transportId:%s]", transportId.c_str());
json data = json::object();
plainTransport->FillJson(data);
request->Accept(data);
break;
}
在构造函数中,创建了socket,并且绑定了通道消息回调
PlainTransport::PlainTransport(RTC::Shared* shared, const std::string& id, RTC::Transport::Listener* listener, json& data)
: RTC::Transport::Transport(shared, id, listener, data)
{
MS_TRACE();
auto jsonListenIpIt = data.find("listenIp");
if (jsonListenIpIt == data.end())
MS_THROW_TYPE_ERROR("missing listenIp");
else if (!jsonListenIpIt->is_object())
MS_THROW_TYPE_ERROR("wrong listenIp (not an object)");
auto jsonIpIt = jsonListenIpIt->find("ip");
if (jsonIpIt == jsonListenIpIt->end())
MS_THROW_TYPE_ERROR("missing listenIp.ip");
else if (!jsonIpIt->is_string())
MS_THROW_TYPE_ERROR("wrong listenIp.ip (not an string)");
//获得内网IP
this->listenIp.ip.assign(jsonIpIt->get<std::string>());
// This may throw.
Utils::IP::NormalizeIp(this->listenIp.ip);
auto jsonAnnouncedIpIt = jsonListenIpIt->find("announcedIp");
if (jsonAnnouncedIpIt != jsonListenIpIt->end())
{
if (!jsonAnnouncedIpIt->is_string())
MS_THROW_TYPE_ERROR("wrong listenIp.announcedIp (not an string");
//获得外网IP
this->listenIp.announcedIp.assign(jsonAnnouncedIpIt->get<std::string>());
}
//获取端口
uint16_t port{ 0 };
auto jsonPortIt = data.find("port");
//判断端口是否合法
if (jsonPortIt != data.end())
{
if (!(jsonPortIt->is_number() && Utils::Json::IsPositiveInteger(*jsonPortIt)))
MS_THROW_TYPE_ERROR("wrong port (not a positive number)");
port = jsonPortIt->get<uint16_t>();
}
auto jsonRtcpMuxIt = data.find("rtcpMux");
if (jsonRtcpMuxIt != data.end())
{
if (!jsonRtcpMuxIt->is_boolean())
MS_THROW_TYPE_ERROR("wrong rtcpMux (not a boolean)");
this->rtcpMux = jsonRtcpMuxIt->get<bool>();
}
auto jsonComediaIt = data.find("comedia");
if (jsonComediaIt != data.end())
{
if (!jsonComediaIt->is_boolean())
MS_THROW_TYPE_ERROR("wrong comedia (not a boolean)");
this->comedia = jsonComediaIt->get<bool>();
}
auto jsonEnableSrtpIt = data.find("enableSrtp");
// clang-format off
if (
jsonEnableSrtpIt != data.end() &&
jsonEnableSrtpIt->is_boolean() &&
jsonEnableSrtpIt->get<bool>()
)
// clang-format on
{
auto jsonSrtpCryptoSuiteIt = data.find("srtpCryptoSuite");
if (jsonSrtpCryptoSuiteIt == data.end() || !jsonSrtpCryptoSuiteIt->is_string())
MS_THROW_TYPE_ERROR("missing srtpCryptoSuite)");
// Ensure it's a crypto suite supported by us.
auto it =
PlainTransport::string2SrtpCryptoSuite.find(jsonSrtpCryptoSuiteIt->get<std::string>());
if (it == PlainTransport::string2SrtpCryptoSuite.end())
MS_THROW_TYPE_ERROR("invalid/unsupported srtpCryptoSuite");
// NOTE: The SRTP crypto suite may change later on connect().
this->srtpCryptoSuite = it->second;
switch (this->srtpCryptoSuite)
{
case RTC::SrtpSession::CryptoSuite::AEAD_AES_256_GCM:
{
this->srtpMasterLength = SrtpAesGcm256MasterLength;
break;
}
case RTC::SrtpSession::CryptoSuite::AEAD_AES_128_GCM:
{
this->srtpMasterLength = SrtpAesGcm128MasterLength;
break;
}
case RTC::SrtpSession::CryptoSuite::AES_CM_128_HMAC_SHA1_80:
case RTC::SrtpSession::CryptoSuite::AES_CM_128_HMAC_SHA1_32:
{
this->srtpMasterLength = SrtpMasterLength;
break;
}
default:
{
MS_ABORT("unknown SRTP crypto suite");
}
}
this->srtpKey = Utils::Crypto::GetRandomString(this->srtpMasterLength);
this->srtpKeyBase64 = Utils::String::Base64Encode(this->srtpKey);//进行base64编码
}
try
{
// This may throw. 通过 listenIp, port 创建 UdpSocket
if (port != 0)
this->udpSocket = new RTC::UdpSocket(this, this->listenIp.ip, port);
else
this->udpSocket = new RTC::UdpSocket(this, this->listenIp.ip);
if (!this->rtcpMux)
{
// This may throw.
this->rtcpUdpSocket = new RTC::UdpSocket(this, this->listenIp.ip);
}
// NOTE: This may throw.
this->shared->channelMessageRegistrator->RegisterHandler(
this->id,
/*channelRequestHandler*/ this,
/*payloadChannelRequestHandler*/ this,
/*payloadChannelNotificationHandler*/ this);
}
catch (const MediaSoupError& error)
{
delete this->udpSocket;
this->udpSocket = nullptr;
delete this->rtcpUdpSocket;
this->rtcpUdpSocket = nullptr;
throw;
}
}