其实很简单,直接放源码吧
inline void WebRtcTransport::OnStunDataReceived(
RTC::TransportTuple* tuple, const uint8_t* data, size_t len)
{
MS_TRACE();
RTC::StunPacket* packet = RTC::StunPacket::Parse(data, len);
if (packet == nullptr)
{
MS_WARN_DEV("ignoring wrong STUN packet received");
return;
}
// Pass it to the IceServer.
this->iceServer->ProcessStunPacket(packet, tuple);
delete packet;
}
// Create a success response.
RTC::StunPacket* response = packet->CreateSuccessResponse();
// Add XOR-MAPPED-ADDRESS.
response->SetXorMappedAddress(tuple->GetRemoteAddress());
// Authenticate the response.
if (this->oldPassword.empty())
response->Authenticate(this->password);
else
response->Authenticate(this->oldPassword);
// Send back.
response->Serialize(StunSerializeBuffer);
this->listener->OnIceServerSendStunPacket(this, response, tuple);
void IceServer::HandleTuple(RTC::TransportTuple* tuple, bool hasUseCandidate)
{
MS_TRACE();
switch (this->state)
{
case IceState::NEW:
{
// There should be no tuples.
MS_ASSERT(
this->tuples.empty(), "state is 'new' but there are %zu tuples", this->tuples.size());
// There shouldn't be a selected tuple.
MS_ASSERT(this->selectedTuple == nullptr, "state is 'new' but there is selected tuple");
if (!hasUseCandidate)
{
MS_DEBUG_TAG(ice, "transition from state 'new' to 'connected'");
// Store the tuple.
auto storedTuple = AddTuple(tuple);
// Mark it as selected tuple.
SetSelectedTuple(storedTuple);
// Update state.
this->state = IceState::CONNECTED;
// Notify the listener.
this->listener->OnIceServerConnected(this);
}
else
{
MS_DEBUG_TAG(ice, "transition from state 'new' to 'completed'");
// Store the tuple.
auto storedTuple = AddTuple(tuple);
// Mark it as selected tuple.
SetSelectedTuple(storedTuple);
// Update state.
this->state = IceState::COMPLETED;
// Notify the listener.
this->listener->OnIceServerCompleted(this);
}
break;
}
case IceState::DISCONNECTED:
{
// There should be no tuples.
MS_ASSERT(
this->tuples.empty(),
"state is 'disconnected' but there are %zu tuples",
this->tuples.size());
// There shouldn't be a selected tuple.
MS_ASSERT(
this->selectedTuple == nullptr, "state is 'disconnected' but there is selected tuple");
if (!hasUseCandidate)
{
MS_DEBUG_TAG(ice, "transition from state 'disconnected' to 'connected'");
// Store the tuple.
auto storedTuple = AddTuple(tuple);
// Mark it as selected tuple.
SetSelectedTuple(storedTuple);
// Update state.
this->state = IceState::CONNECTED;
// Notify the listener.
this->listener->OnIceServerConnected(this);
}
else
{
MS_DEBUG_TAG(ice, "transition from state 'disconnected' to 'completed'");
// Store the tuple.
auto storedTuple = AddTuple(tuple);
// Mark it as selected tuple.
SetSelectedTuple(storedTuple);
// Update state.
this->state = IceState::COMPLETED;
// Notify the listener.
this->listener->OnIceServerCompleted(this);
}
break;
}
case IceState::CONNECTED:
{
// There should be some tuples.
MS_ASSERT(!this->tuples.empty(), "state is 'connected' but there are no tuples");
// There should be a selected tuple.
MS_ASSERT(
this->selectedTuple != nullptr, "state is 'connected' but there is not selected tuple");
if (!hasUseCandidate)
{
// If a new tuple store it.
if (HasTuple(tuple) == nullptr)
AddTuple(tuple);
}
else
{
MS_DEBUG_TAG(ice, "transition from state 'connected' to 'completed'");
auto storedTuple = HasTuple(tuple);
// If a new tuple store it.
if (storedTuple == nullptr)
storedTuple = AddTuple(tuple);
// Mark it as selected tuple.
SetSelectedTuple(storedTuple);
// Update state.
this->state = IceState::COMPLETED;
// Notify the listener.
this->listener->OnIceServerCompleted(this);
}
break;
}
case IceState::COMPLETED:
{
// There should be some tuples.
MS_ASSERT(!this->tuples.empty(), "state is 'completed' but there are no tuples");
// There should be a selected tuple.
MS_ASSERT(
this->selectedTuple != nullptr, "state is 'completed' but there is not selected tuple");
if (!hasUseCandidate)
{
// If a new tuple store it.
if (HasTuple(tuple) == nullptr)
AddTuple(tuple);
}
else
{
auto storedTuple = HasTuple(tuple);
// If a new tuple store it.
if (storedTuple == nullptr)
storedTuple = AddTuple(tuple);
// Mark it as selected tuple.
SetSelectedTuple(storedTuple);
}
break;
}
}
}
最后通知交互完成
inline void WebRtcTransport::OnIceServerConnected(const RTC::IceServer* /*iceServer*/)
{
MS_TRACE();
MS_DEBUG_TAG(ice, "ICE connected");
// Notify the Node WebRtcTransport.
json data = json::object();
data["iceState"] = "connected";
Channel::Notifier::Emit(this->id, "icestatechange", data);
// If ready, run the DTLS handler.
MayRunDtlsTransport();
}
inline void WebRtcTransport::OnIceServerCompleted(const RTC::IceServer* /*iceServer*/)
{
MS_TRACE();
MS_DEBUG_TAG(ice, "ICE completed");
// Notify the Node WebRtcTransport.
json data = json::object();
data["iceState"] = "completed";
Channel::Notifier::Emit(this->id, "icestatechange", data);
// If ready, run the DTLS handler.
MayRunDtlsTransport();
}