-
-
Notifications
You must be signed in to change notification settings - Fork 520
Open
Description
This is the code of my server (C++).
server.Post("/connection", [](const httplib::Request &req, httplib::Response &res) {
try {
json data = json::parse(req.body);
json offer = data["offer"];
json candidatesOffer = data["candidatesOffer"];
// Two promises are used to synchronously wait for the WebRTC callback
std::promise<json> promiseAnswer;
std::promise<json> promiseCandidatesAnswer;
auto futureAnswer = promiseAnswer.get_future();
auto futureCandidatesAnswer = promiseCandidatesAnswer.get_future();
rtc::Configuration config;
// config.iceServers.emplace_back("stun:stun.l.google.com:19302");
// config.iceServers.clear();
// config.enableMdns = false;
// config.portRangeStart = 50000;
// config.portRangeEnd = 50100;
// Use shared_ptr to avoid automatic destruction
auto pc = std::make_shared<rtc::PeerConnection>(config);
// Listen to the local SDP (answer)
pc->onLocalDescription([&promiseAnswer](rtc::Description desc) {
json ans = {
{"sdp", std::string(desc)},
{"type", std::string(desc.typeString())}
};
promiseAnswer.set_value(ans);
});
// Collect candidates
std::vector<json> localCandidates;
pc->onLocalCandidate([&localCandidates](rtc::Candidate c) {
json item = {
{"candidate", c.candidate()},
{"sdpMid", c.mid()},
{"sdpMLineIndex", 0 }
};
localCandidates.push_back(item);
});
// After ICE is completed, return the candidates
pc->onGatheringStateChange([&promiseCandidatesAnswer, &localCandidates](auto state) {
if (state == rtc::PeerConnection::GatheringState::Complete) {
promiseCandidatesAnswer.set_value(localCandidates);
}
});
pc->onStateChange([](auto state){
std::cout << "onStateChange: " << state << std::endl;
});
pc->onIceStateChange([](auto state){
std::cout << "onIceStateChange: " << state << std::endl;
});
pc->onSignalingStateChange([](auto state){
std::cout << "onIceStateChange: " << state << std::endl;
});
// Set remote offer
rtc::Description remote(
offer["sdp"].get<std::string>(),
offer["type"].get<std::string>()
);
pc->setRemoteDescription(remote);
// 添加 remote candidates
for (auto &c : candidatesOffer)
{
std::string candidateStr = c["candidate"];
std::string mid;
if (c["sdpMid"].is_string()) {
mid = c["sdpMid"];
} else {
mid = std::to_string(c["sdpMid"].get<int>());
}
rtc::Candidate cand(candidateStr, mid);
pc->addRemoteCandidate(cand);
}
// Wait for the generation of 'answer' and 'candidates' (blocking, but it's fine)
json answer = futureAnswer.get();
json candidatesAnswer = futureCandidatesAnswer.get();
// Return the data all at once in the end
json response = {
{"success", true},
{"code",200},
{"data", {
{"answer", answer},
{"candidatesAnswer", candidatesAnswer}
}}
};
res.set_content(response.dump(4), "application/json");
}
catch (...) {
res.status = 500;
res.set_content("{\"error\":\"internal error\"}", "application/json");
}
});Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels