upgrade safe version 3
This commit is contained in:
parent
72c09ad308
commit
cacb3dd569
|
|
@ -39,7 +39,7 @@ PeerServer::PeerServer(SignalingManager& sig,
|
|||
sig_.sendSdp(sdp);
|
||||
sdpDone_ = true;
|
||||
|
||||
// std::cout << "[Server] Sent ANSWER\n";
|
||||
std::cout << "[Server] Sent ANSWER\n";
|
||||
});
|
||||
|
||||
/* ===== LOCAL ICE ===== */
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
#include "WebRTCTransport.hpp"
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
|
||||
/* ================================
|
||||
* Constructor
|
||||
* ================================ */
|
||||
WebRTCTransport::WebRTCTransport()
|
||||
: dcOpen_(false),
|
||||
haveRemoteOffer_(false),
|
||||
answerCreated_(false),
|
||||
localAnswerSent_(false)
|
||||
{
|
||||
rtc::Configuration cfg;
|
||||
|
|
@ -12,71 +15,103 @@ WebRTCTransport::WebRTCTransport()
|
|||
|
||||
pc_ = std::make_shared<rtc::PeerConnection>(cfg);
|
||||
|
||||
/* ===== LOCAL ICE ===== */
|
||||
pc_->onLocalCandidate([this](rtc::Candidate c){
|
||||
/* =====================================================
|
||||
* LOCAL SDP – REGISTER ONCE (CRITICAL FIX)
|
||||
* ===================================================== */
|
||||
pc_->onLocalDescription([this](rtc::Description d) {
|
||||
if (d.type() != rtc::Description::Type::Answer)
|
||||
return;
|
||||
|
||||
if (localAnswerSent_) {
|
||||
std::cout << "[Transport] Duplicate local ANSWER ignored\n";
|
||||
return;
|
||||
}
|
||||
|
||||
localAnswerSent_ = true;
|
||||
|
||||
std::string sdp = std::string(d);
|
||||
|
||||
if (onLocalSdpCb_) {
|
||||
onLocalSdpCb_(sdp);
|
||||
} else {
|
||||
/* ultra-safe: cache if callback registered late */
|
||||
cachedAnswer_ = sdp;
|
||||
std::cout << "[Transport] ANSWER cached (no callback yet)\n";
|
||||
}
|
||||
});
|
||||
|
||||
/* =====================================================
|
||||
* LOCAL ICE
|
||||
* ===================================================== */
|
||||
pc_->onLocalCandidate([this](rtc::Candidate c) {
|
||||
if (onLocalIceCb_) {
|
||||
onLocalIceCb_(c.candidate(), c.mid());
|
||||
}
|
||||
});
|
||||
|
||||
/* ===== DATA CHANNEL ===== */
|
||||
pc_->onDataChannel([this](std::shared_ptr<rtc::DataChannel> dc){
|
||||
/* =====================================================
|
||||
* DATA CHANNEL
|
||||
* ===================================================== */
|
||||
pc_->onDataChannel([this](std::shared_ptr<rtc::DataChannel> dc) {
|
||||
dc_ = dc;
|
||||
|
||||
dc_->onOpen([this]{
|
||||
dc_->onOpen([this] {
|
||||
dcOpen_ = true;
|
||||
if (onDcOpenCb_) onDcOpenCb_();
|
||||
if (onDcOpenCb_)
|
||||
onDcOpenCb_();
|
||||
});
|
||||
|
||||
dc_->onMessage([this](rtc::message_variant msg){
|
||||
dc_->onClosed([this] {
|
||||
dcOpen_ = false;
|
||||
std::cout << "[Transport] DataChannel closed\n";
|
||||
});
|
||||
|
||||
dc_->onMessage([this](rtc::message_variant msg) {
|
||||
if (const auto* s = std::get_if<std::string>(&msg)) {
|
||||
if (onDcMessageCb_) onDcMessageCb_(*s);
|
||||
if (onDcMessageCb_)
|
||||
onDcMessageCb_(*s);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/* ===== CALLBACK REG ===== */
|
||||
/* ================================
|
||||
* CALLBACK REGISTRATION
|
||||
* ================================ */
|
||||
|
||||
void WebRTCTransport::onLocalSdp(
|
||||
std::function<void(std::string)> cb)
|
||||
{
|
||||
onLocalSdpCb_ = cb;
|
||||
onLocalSdpCb_ = std::move(cb);
|
||||
|
||||
pc_->onLocalDescription([this](rtc::Description d){
|
||||
if (!onLocalSdpCb_) return;
|
||||
|
||||
if (d.type() != rtc::Description::Type::Answer)
|
||||
return;
|
||||
|
||||
if (localAnswerSent_) {
|
||||
std::cout << "[Transport] Ignore duplicate local ANSWER\n";
|
||||
return;
|
||||
}
|
||||
|
||||
localAnswerSent_ = true;
|
||||
onLocalSdpCb_(std::string(d));
|
||||
});
|
||||
/* flush cached ANSWER if any */
|
||||
if (cachedAnswer_) {
|
||||
onLocalSdpCb_(*cachedAnswer_);
|
||||
cachedAnswer_.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void WebRTCTransport::onLocalIce(
|
||||
std::function<void(std::string,std::string)> cb)
|
||||
std::function<void(std::string, std::string)> cb)
|
||||
{
|
||||
onLocalIceCb_ = cb;
|
||||
onLocalIceCb_ = std::move(cb);
|
||||
}
|
||||
|
||||
void WebRTCTransport::onDcOpen(std::function<void()> cb)
|
||||
void WebRTCTransport::onDcOpen(
|
||||
std::function<void()> cb)
|
||||
{
|
||||
onDcOpenCb_ = cb;
|
||||
onDcOpenCb_ = std::move(cb);
|
||||
}
|
||||
|
||||
void WebRTCTransport::onDcMessage(
|
||||
std::function<void(const std::string&)> cb)
|
||||
{
|
||||
onDcMessageCb_ = cb;
|
||||
onDcMessageCb_ = std::move(cb);
|
||||
}
|
||||
|
||||
/* ===== SDP ===== */
|
||||
/* ================================
|
||||
* SDP
|
||||
* ================================ */
|
||||
|
||||
void WebRTCTransport::setRemoteOffer(const std::string& sdp)
|
||||
{
|
||||
|
|
@ -85,30 +120,25 @@ void WebRTCTransport::setRemoteOffer(const std::string& sdp)
|
|||
return;
|
||||
}
|
||||
|
||||
std::cout << "[Transport] Set remote OFFER\n";
|
||||
|
||||
pc_->setRemoteDescription(
|
||||
rtc::Description(sdp,
|
||||
rtc::Description::Type::Offer));
|
||||
|
||||
haveRemoteOffer_ = true;
|
||||
|
||||
/* ===== FLUSH ICE BUFFER ===== */
|
||||
/* ===== Flush ICE buffer ===== */
|
||||
if (!iceBuffer_.empty()) {
|
||||
std::cout << "[Transport] Flush ICE buffer: "
|
||||
<< iceBuffer_.size()
|
||||
<< " candidate(s)\n";
|
||||
|
||||
for (auto& c : iceBuffer_) {
|
||||
std::cout << "[Transport] + "
|
||||
<< c.candidate()
|
||||
<< "\n";
|
||||
pc_->addRemoteCandidate(c);
|
||||
}
|
||||
|
||||
iceBuffer_.clear();
|
||||
} else {
|
||||
std::cout << "[Transport] ICE buffer empty\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void WebRTCTransport::createAnswer()
|
||||
|
|
@ -125,16 +155,18 @@ void WebRTCTransport::createAnswer()
|
|||
pc_->setLocalDescription(rtc::Description::Type::Answer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void WebRTCTransport::setRemoteAnswer(const std::string& sdp)
|
||||
{
|
||||
std::cout << "[Transport] Set remote ANSWER\n";
|
||||
|
||||
pc_->setRemoteDescription(
|
||||
rtc::Description(sdp,
|
||||
rtc::Description::Type::Answer));
|
||||
}
|
||||
|
||||
/* ===== ICE ===== */
|
||||
/* ================================
|
||||
* ICE
|
||||
* ================================ */
|
||||
|
||||
void WebRTCTransport::addRemoteIce(
|
||||
const std::string& cand,
|
||||
|
|
@ -149,7 +181,9 @@ void WebRTCTransport::addRemoteIce(
|
|||
}
|
||||
}
|
||||
|
||||
/* ===== DATA ===== */
|
||||
/* ================================
|
||||
* DATA
|
||||
* ================================ */
|
||||
|
||||
void WebRTCTransport::sendMessage(const std::string& msg)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include <rtc/rtc.hpp>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
class WebRTCTransport
|
||||
{
|
||||
class WebRTCTransport {
|
||||
public:
|
||||
WebRTCTransport();
|
||||
|
||||
|
|
@ -15,37 +16,34 @@ public:
|
|||
void onDcOpen(std::function<void()> cb);
|
||||
void onDcMessage(std::function<void(const std::string&)> cb);
|
||||
|
||||
void createOffer();
|
||||
void createAnswer();
|
||||
void setRemoteOffer(const std::string& sdp);
|
||||
void createAnswer();
|
||||
void setRemoteAnswer(const std::string& sdp);
|
||||
void addRemoteIce(const std::string& cand, const std::string& mid);
|
||||
|
||||
void addRemoteIce(const std::string& cand,
|
||||
const std::string& mid);
|
||||
|
||||
void sendMessage(const std::string& msg);
|
||||
|
||||
private:
|
||||
/* WebRTC core */
|
||||
std::shared_ptr<rtc::PeerConnection> pc_;
|
||||
std::shared_ptr<rtc::DataChannel> dc_;
|
||||
|
||||
// ===== state =====
|
||||
bool dcOpen_ = false;
|
||||
|
||||
// SDP state
|
||||
bool haveRemoteOffer_ = false; // set sau setRemoteOffer()
|
||||
bool answerCreated_ = false; // set sau createAnswer()
|
||||
|
||||
bool localAnswerSent_ = false;
|
||||
|
||||
|
||||
// ===== ICE buffer =====
|
||||
std::vector<rtc::Candidate> iceBuffer_;
|
||||
|
||||
// ===== callbacks =====
|
||||
/* Callbacks */
|
||||
std::function<void(std::string)> onLocalSdpCb_;
|
||||
std::function<void(std::string,std::string)> onLocalIceCb_;
|
||||
std::function<void()> onDcOpenCb_;
|
||||
std::function<void(const std::string&)> onDcMessageCb_;
|
||||
|
||||
/* State */
|
||||
bool dcOpen_{false};
|
||||
bool haveRemoteOffer_{false};
|
||||
bool localAnswerSent_{false};
|
||||
|
||||
/* ICE buffer */
|
||||
std::vector<rtc::Candidate> iceBuffer_;
|
||||
|
||||
/*FIX: cache SDP if callback registered late */
|
||||
std::optional<std::string> cachedAnswer_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue