Support multiple ice connections

This commit is contained in:
dijunkun
2023-08-17 17:31:08 +08:00
parent a9db3d290b
commit 3a55dd0938
16 changed files with 335 additions and 232 deletions

View File

@@ -1,6 +1,6 @@
[signal server] [signal server]
ip = localhost ip = localhost
port = 9002 port = 9095
[stun server] [stun server]
ip = 120.77.216.215 ip = 120.77.216.215

33
src/common/common.h Normal file
View File

@@ -0,0 +1,33 @@
#ifndef _COMMON_H_
#define _COMMON_H_
#include <iostream>
constexpr size_t HASH_STRING_PIECE(const char *string_piece) {
std::size_t result = 0;
while (*string_piece) {
result = (result * 131) + *string_piece++;
}
return result;
}
constexpr size_t operator"" _H(const char *string_piece, size_t) {
return HASH_STRING_PIECE(string_piece);
}
inline const std::string GetIceUsername(const std::string &sdp) {
std::string result = "";
std::string start = "ice-ufrag:";
std::string end = "\r\n";
size_t startPos = sdp.find(start);
size_t endPos = sdp.find(end);
if (startPos != std::string::npos && endPos != std::string::npos) {
result = sdp.substr(startPos + start.length(),
endPos - startPos - start.length());
}
return result;
}
#endif

View File

@@ -4,31 +4,21 @@
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include <thread> #include <thread>
#include "common.h"
#include "log.h" #include "log.h"
using nlohmann::json; using nlohmann::json;
constexpr size_t HASH_STRING_PIECE(const char *string_piece) {
std::size_t result = 0;
while (*string_piece) {
result = (result * 131) + *string_piece++;
}
return result;
}
constexpr size_t operator"" _H(const char *string_piece, size_t) {
return HASH_STRING_PIECE(string_piece);
}
const std::vector<std::string> ice_status = { const std::vector<std::string> ice_status = {
"JUICE_STATE_DISCONNECTED", "JUICE_STATE_GATHERING", "JUICE_STATE_DISCONNECTED", "JUICE_STATE_GATHERING",
"JUICE_STATE_CONNECTING", "JUICE_STATE_CONNECTED", "JUICE_STATE_CONNECTING", "JUICE_STATE_CONNECTED",
"JUICE_STATE_COMPLETED", "JUICE_STATE_FAILED"}; "JUICE_STATE_COMPLETED", "JUICE_STATE_FAILED"};
IceTransmission::IceTransmission( IceTransmission::IceTransmission(
WsTransmission *ice_ws_transmission, bool offer_peer, WsTransmission *ice_ws_transmission,
std::function<void(const char *, size_t)> on_receive_ice_msg) std::function<void(const char *, size_t)> on_receive_ice_msg)
: ice_ws_transport_(ice_ws_transmission), : offer_peer_(offer_peer),
ice_ws_transport_(ice_ws_transmission),
on_receive_ice_msg_cb_(on_receive_ice_msg) {} on_receive_ice_msg_cb_(on_receive_ice_msg) {}
IceTransmission::~IceTransmission() {} IceTransmission::~IceTransmission() {}
@@ -50,43 +40,15 @@ int IceTransmission::InitIceTransmission(std::string &ip, int port) {
LOG_INFO("gather_done"); LOG_INFO("gather_done");
// non-trickle // non-trickle
if (user_ptr) { if (user_ptr) {
static_cast<IceTransmission *>(user_ptr)->GetLocalSdp(); IceTransmission *ice_transmission_obj =
static_cast<IceTransmission *>(user_ptr)->SendOffer(); static_cast<IceTransmission *>(user_ptr);
} if (ice_transmission_obj->offer_peer_) {
}, ice_transmission_obj->GetLocalSdp();
[](juice_agent_t *agent, const char *data, size_t size, void *user_ptr) { ice_transmission_obj->SendOffer();
if (user_ptr && } else {
static_cast<IceTransmission *>(user_ptr)->on_receive_ice_msg_cb_) { ice_transmission_obj->CreateAnswer();
static_cast<IceTransmission *>(user_ptr)->on_receive_ice_msg_cb_( ice_transmission_obj->SendAnswer();
data, size); }
}
},
this);
return 0;
}
int IceTransmission::InitIceTransmission(std::string &ip, int port,
std::string const &id) {
transmission_id_ = id;
ice_agent_ = new IceAgent(ip, port);
ice_agent_->CreateIceAgent(
[](juice_agent_t *agent, juice_state_t state, void *user_ptr) {
LOG_INFO("state_change: {}", ice_status[state]);
},
[](juice_agent_t *agent, const char *sdp, void *user_ptr) {
LOG_INFO("candadite: {}", sdp);
// trickle
// static_cast<PeerConnection
// *>(user_ptr)->SendAnswerLocalCandidate(sdp);
},
[](juice_agent_t *agent, void *user_ptr) {
LOG_INFO("gather_done");
// non-trickle
if (user_ptr) {
static_cast<IceTransmission *>(user_ptr)->CreateAnswer();
static_cast<IceTransmission *>(user_ptr)->SendAnswer();
} }
}, },
[](juice_agent_t *agent, const char *data, size_t size, void *user_ptr) { [](juice_agent_t *agent, const char *data, size_t size, void *user_ptr) {
@@ -109,7 +71,8 @@ int IceTransmission::DestroyIceTransmission() {
int IceTransmission::CreateTransmission(const std::string &transmission_id) { int IceTransmission::CreateTransmission(const std::string &transmission_id) {
LOG_INFO("Create transport"); LOG_INFO("Create transport");
offer_peer_ = true; offer_peer_ = false;
transmission_id_ = transmission_id;
// if (SignalStatus::Connected != signal_status_) { // if (SignalStatus::Connected != signal_status_) {
// LOG_ERROR("Not connect to signalserver"); // LOG_ERROR("Not connect to signalserver");
@@ -129,7 +92,7 @@ int IceTransmission::CreateTransmission(const std::string &transmission_id) {
int IceTransmission::JoinTransmission(const std::string &transmission_id) { int IceTransmission::JoinTransmission(const std::string &transmission_id) {
LOG_INFO("Join transport"); LOG_INFO("Join transport");
offer_peer_ = false; offer_peer_ = true;
transmission_id_ = transmission_id; transmission_id_ = transmission_id;
// if (SignalStatus::Connected != signal_status_) { // if (SignalStatus::Connected != signal_status_) {
@@ -154,6 +117,7 @@ int IceTransmission::GetLocalSdp() {
int IceTransmission::SetRemoteSdp(const std::string &remote_sdp) { int IceTransmission::SetRemoteSdp(const std::string &remote_sdp) {
ice_agent_->SetRemoteSdp(remote_sdp.c_str()); ice_agent_->SetRemoteSdp(remote_sdp.c_str());
remote_ice_username_ = GetIceUsername(remote_sdp);
return 0; return 0;
} }
@@ -199,7 +163,8 @@ int IceTransmission::CreateAnswer() {
int IceTransmission::SendAnswer() { int IceTransmission::SendAnswer() {
json message = {{"type", "answer"}, json message = {{"type", "answer"},
{"transmission_id", transmission_id_}, {"transmission_id", transmission_id_},
{"sdp", local_sdp_}}; {"sdp", local_sdp_},
{"guest", remote_ice_username_}};
LOG_INFO("Send answer:\n{}", message.dump().c_str()); LOG_INFO("Send answer:\n{}", message.dump().c_str());
if (ice_ws_transport_) { if (ice_ws_transport_) {
@@ -247,6 +212,16 @@ void IceTransmission::OnReceiveMessage(const std::string &msg) {
switch (HASH_STRING_PIECE(type.c_str())) { switch (HASH_STRING_PIECE(type.c_str())) {
case "offer"_H: { case "offer"_H: {
remote_sdp_ = j["sdp"].get<std::string>();
if (remote_sdp_.empty()) {
LOG_INFO("Invalid remote sdp");
} else {
LOG_INFO("Receive remote sdp [{}]", remote_sdp_);
SetRemoteSdp(remote_sdp_);
GatherCandidates();
}
break; break;
} }
case "transmission_id"_H: { case "transmission_id"_H: {

View File

@@ -8,13 +8,12 @@
class IceTransmission { class IceTransmission {
public: public:
IceTransmission(WsTransmission *ice_ws_transmission, IceTransmission(bool offer_peer, WsTransmission *ice_ws_transmission,
std::function<void(const char *, size_t)> on_receive_ice_msg); std::function<void(const char *, size_t)> on_receive_ice_msg);
~IceTransmission(); ~IceTransmission();
int InitIceTransmission(std::string &ip, int port); int InitIceTransmission(std::string &ip, int port);
int InitIceTransmission(std::string &ip, int port, std::string const &id);
int DestroyIceTransmission(); int DestroyIceTransmission();
@@ -27,7 +26,7 @@ class IceTransmission {
void OnReceiveMessage(const std::string &msg); void OnReceiveMessage(const std::string &msg);
private: public:
int GatherCandidates(); int GatherCandidates();
int GetLocalSdp(); int GetLocalSdp();
@@ -56,6 +55,7 @@ class IceTransmission {
std::function<void(const char *, size_t)> on_receive_ice_msg_cb_ = nullptr; std::function<void(const char *, size_t)> on_receive_ice_msg_cb_ = nullptr;
std::string local_sdp_; std::string local_sdp_;
std::string remote_sdp_; std::string remote_sdp_;
std::string remote_ice_username_;
std::string local_candidates_; std::string local_candidates_;
std::string remote_candidates_; std::string remote_candidates_;
unsigned int connection_id_ = 0; unsigned int connection_id_ = 0;

View File

@@ -3,6 +3,7 @@
#include <regex> #include <regex>
#include "INIReader.h" #include "INIReader.h"
#include "common.h"
#include "log.h" #include "log.h"
#include "nlohmann/json.hpp" #include "nlohmann/json.hpp"
@@ -19,40 +20,69 @@ PeerConnection::PeerConnection() {}
PeerConnection::~PeerConnection() {} PeerConnection::~PeerConnection() {}
int PeerConnection::Create(PeerConnectionParams params, const std::string &id) { int PeerConnection::Create(PeerConnectionParams params,
const std::string &transmission_id) {
INIReader reader(params.cfg_path); INIReader reader(params.cfg_path);
std::string cfg_signal_server_ip = reader.Get("signal server", "ip", "-1"); cfg_signal_server_ip_ = reader.Get("signal server", "ip", "-1");
std::string cfg_signal_server_port = cfg_signal_server_port_ = reader.Get("signal server", "port", "-1");
reader.Get("signal server", "port", "-1"); cfg_stun_server_ip_ = reader.Get("stun server", "ip", "-1");
std::string cfg_stun_server_ip = reader.Get("stun server", "ip", "-1"); cfg_stun_server_port_ = reader.Get("stun server", "port", "-1");
std::string cfg_stun_server_port = reader.Get("stun server", "port", "-1");
std::regex regex("\n"); std::regex regex("\n");
LOG_INFO("Read config success"); LOG_INFO("Read config success");
int signal_server_port = stoi(cfg_signal_server_port); signal_server_port_ = stoi(cfg_signal_server_port_);
int stun_server_port = stoi(cfg_stun_server_port); stun_server_port_ = stoi(cfg_stun_server_port_);
on_receive_ws_msg_ = [this](const std::string &msg) { on_receive_ws_msg_ = [this](const std::string &msg) {
do {
} while (!ice_transmission_);
auto j = json::parse(msg); auto j = json::parse(msg);
std::string type = j["type"]; std::string type = j["type"];
auto itr = siganl_types.find(type); LOG_INFO("msg type :{}", type.c_str());
if (itr != siganl_types.end()) { switch (HASH_STRING_PIECE(type.c_str())) {
LOG_INFO("msg type :{}", itr->first); case "ws_connection_id"_H: {
switch (itr->second) { ws_connection_id_ = j["ws_connection_id"].get<unsigned int>();
case 1: { LOG_INFO("Receive local peer websocket connection id [{}]",
ws_connection_id_ = j["ws_connection_id"].get<unsigned int>(); ws_connection_id_);
LOG_INFO("Receive local peer websocket connection id [{}]", signal_status_ = SignalStatus::Connected;
ws_connection_id_); break;
signal_status_ = SignalStatus::Connected; }
break; case "transmission_id"_H: {
if (j["status"].get<std::string>() == "success") {
transmission_id_ = j["transmission_id"].get<std::string>();
LOG_INFO("Create transmission success with id [{}]",
transmission_id_);
} else if (j["status"].get<std::string>() == "fail") {
LOG_WARN("Create transmission failed with id [{}], due to [{}]",
transmission_id_, j["reason"].get<std::string>().c_str());
} }
default: { break;
ice_transmission_->OnReceiveMessage(msg); }
break; case "offer"_H: {
std::string remote_sdp = j["sdp"].get<std::string>();
if (remote_sdp.empty()) {
LOG_INFO("Invalid remote sdp");
} else {
LOG_INFO("Receive remote sdp [{}]", remote_sdp);
ice_transmission_ =
new IceTransmission(false, ws_transport_, on_receive_ice_msg_);
std::string ice_username = GetIceUsername(remote_sdp);
ice_transmission_list_[ice_username] = ice_transmission_;
ice_transmission_->InitIceTransmission(cfg_stun_server_ip_,
stun_server_port_);
ice_transmission_->SetRemoteSdp(remote_sdp);
ice_transmission_->GatherCandidates();
} }
break;
}
default: {
ice_transmission_->OnReceiveMessage(msg);
break;
} }
} }
}; };
@@ -63,23 +93,28 @@ int PeerConnection::Create(PeerConnectionParams params, const std::string &id) {
}; };
ws_transport_ = new WsTransmission(on_receive_ws_msg_); ws_transport_ = new WsTransmission(on_receive_ws_msg_);
uri_ = "ws://" + cfg_signal_server_ip + ":" + cfg_signal_server_port; uri_ = "ws://" + cfg_signal_server_ip_ + ":" + cfg_signal_server_port_;
if (ws_transport_) { if (ws_transport_) {
ws_transport_->Connect(uri_); ws_transport_->Connect(uri_);
} }
ice_transmission_ = new IceTransmission(ws_transport_, on_receive_ice_msg_);
ice_transmission_->InitIceTransmission(cfg_stun_server_ip, stun_server_port);
do { do {
LOG_INFO("GetSignalStatus = {}", GetSignalStatus()); LOG_INFO("GetSignalStatus = {}", GetSignalStatus());
} while (SignalStatus::Connected != GetSignalStatus()); } while (SignalStatus::Connected != GetSignalStatus());
ice_transmission_->CreateTransmission(id); // ice_transmission_->CreateTransmission(transmission_id);
json message = {{"type", "create_transmission"},
{"transmission_id", transmission_id}};
if (ws_transport_) {
ws_transport_->Send(message.dump());
LOG_INFO("Send create transmission request: {}", message.dump().c_str());
}
return 0; return 0;
} }
int PeerConnection::Join(PeerConnectionParams params, const std::string &id) { int PeerConnection::Join(PeerConnectionParams params,
const std::string &transmission_id) {
INIReader reader(params.cfg_path); INIReader reader(params.cfg_path);
std::string cfg_signal_server_ip = reader.Get("signal server", "ip", "-1"); std::string cfg_signal_server_ip = reader.Get("signal server", "ip", "-1");
std::string cfg_signal_server_port = std::string cfg_signal_server_port =
@@ -120,7 +155,7 @@ int PeerConnection::Join(PeerConnectionParams params, const std::string &id) {
LOG_INFO("Receive data: [{}]", msg.c_str()); LOG_INFO("Receive data: [{}]", msg.c_str());
}; };
transmission_id_ = id; transmission_id_ = transmission_id;
ws_transport_ = new WsTransmission(on_receive_ws_msg_); ws_transport_ = new WsTransmission(on_receive_ws_msg_);
uri_ = "ws://" + cfg_signal_server_ip + ":" + cfg_signal_server_port; uri_ = "ws://" + cfg_signal_server_ip + ":" + cfg_signal_server_port;
@@ -128,9 +163,9 @@ int PeerConnection::Join(PeerConnectionParams params, const std::string &id) {
ws_transport_->Connect(uri_); ws_transport_->Connect(uri_);
} }
ice_transmission_ = new IceTransmission(ws_transport_, on_receive_ice_msg_); ice_transmission_ =
ice_transmission_->InitIceTransmission(cfg_stun_server_ip, stun_server_port, new IceTransmission(true, ws_transport_, on_receive_ice_msg_);
id); ice_transmission_->InitIceTransmission(cfg_stun_server_ip, stun_server_port);
do { do {
LOG_INFO("GetSignalStatus = {}", GetSignalStatus()); LOG_INFO("GetSignalStatus = {}", GetSignalStatus());

View File

@@ -2,6 +2,7 @@
#define _PEER_CONNECTION_H_ #define _PEER_CONNECTION_H_
#include <iostream> #include <iostream>
#include <map>
#include "ice_transmission.h" #include "ice_transmission.h"
#include "ws_transmission.h" #include "ws_transmission.h"
@@ -35,8 +36,15 @@ class PeerConnection {
private: private:
std::string uri_ = ""; std::string uri_ = "";
std::string cfg_signal_server_ip_;
std::string cfg_signal_server_port_;
std::string cfg_stun_server_ip_;
std::string cfg_stun_server_port_;
int signal_server_port_ = 0;
int stun_server_port_ = 0;
WsTransmission *ws_transport_ = nullptr; WsTransmission *ws_transport_ = nullptr;
IceTransmission *ice_transmission_ = nullptr; IceTransmission *ice_transmission_ = nullptr;
std::map<std::string, IceTransmission *> ice_transmission_list_;
std::function<void(const std::string &)> on_receive_ws_msg_ = nullptr; std::function<void(const std::string &)> on_receive_ws_msg_ = nullptr;
std::function<void(const char *, size_t)> on_receive_ice_msg_ = nullptr; std::function<void(const char *, size_t)> on_receive_ice_msg_ = nullptr;
unsigned int ws_connection_id_ = 0; unsigned int ws_connection_id_ = 0;

View File

@@ -1,8 +1,12 @@
#include <iostream>
#include "signal_server.h" #include "signal_server.h"
int main() { int main(int argc, char* argv[]) {
SignalServer s; SignalServer s;
// connect ws://localhost:9002 std::string port = argv[1];
s.run(); std::cout << "Port: " << port << std::endl;
return 0; s.run(std::stoi(port));
return 0;
} }

View File

@@ -1,6 +0,0 @@
#include "sdp_manager.h"
SdpManager ::SdpManager() {}
SdpManager ::~SdpManager() {}

View File

@@ -1,28 +0,0 @@
#ifndef _SDP_MANAGER_H_
#define _SDP_MANAGER_H_
#include <iostream>
#include <map>
class SdpManager {
public:
SdpManager();
~SdpManager();
public:
int AddOfferSdpToConnection(std::string &sdp, std::string &connection_id);
int AddAnswerSdpToConnection(std::string &sdp, std::string &connection_id);
int UpdateOfferSdpToConnection(std::string &sdp, std::string &connection_id);
int UpdateAnswerSdpToConnection(std::string &sdp, std::string &connection_id);
const std::string &GetOfferSdpFromConnection(std::string &connection_id);
const std::string &GetAnswerSdpFromConnection(std::string &connection_id);
int RemoveConnetion(std::string &connection_id);
private:
// <connection_id, <offer_sdp, answer_sdp>.
std::map<std::string, std::pair<std::string, std::string>> answer_hdl_map_;
};
#endif

View File

@@ -1,20 +1,9 @@
#include "signal_server.h" #include "signal_server.h"
#include "common.h"
#include "log.h" #include "log.h"
constexpr size_t HASH_STRING_PIECE(const char* string_piece) { const std::string GenerateTransmissionId() {
std::size_t result = 0;
while (*string_piece) {
result = (result * 131) + *string_piece++;
}
return result;
}
constexpr size_t operator"" _H(const char* string_piece, size_t) {
return HASH_STRING_PIECE(string_piece);
}
const std::string gen_random_6() {
static const char alphanum[] = "0123456789"; static const char alphanum[] = "0123456789";
std::string random_id; std::string random_id;
random_id.reserve(6); random_id.reserve(6);
@@ -65,7 +54,7 @@ bool SignalServer::on_open(websocketpp::connection_hdl hdl) {
} }
bool SignalServer::on_close(websocketpp::connection_hdl hdl) { bool SignalServer::on_close(websocketpp::connection_hdl hdl) {
LOG_INFO("Websocket onnection [{}] closed", ws_connection_id_++); LOG_INFO("Websocket onnection [{}] closed", ws_connection_id_);
ws_connections_.erase(hdl); ws_connections_.erase(hdl);
return true; return true;
} }
@@ -82,9 +71,9 @@ bool SignalServer::on_pong(websocketpp::connection_hdl hdl, std::string s) {
return true; return true;
} }
void SignalServer::run() { void SignalServer::run(uint16_t port) {
// Listen on port 9002 // Listen on port 9093
server_.listen(9002); server_.listen(port);
// Queues a connection accept operation // Queues a connection accept operation
server_.start_accept(); server_.start_accept();
@@ -102,36 +91,38 @@ void SignalServer::on_message(websocketpp::connection_hdl hdl,
std::string payload = msg->get_payload(); std::string payload = msg->get_payload();
auto j = json::parse(payload); auto j = json::parse(payload);
std::string type = j["type"]; std::string type = j["type"].get<std::string>();
switch (HASH_STRING_PIECE(type.c_str())) { switch (HASH_STRING_PIECE(type.c_str())) {
case "create_transmission"_H: { case "create_transmission"_H: {
transmission_id_ = j["transmission_id"]; std::string transmission_id = j["transmission_id"].get<std::string>();
LOG_INFO("Receive create transmission request with id [{}]", LOG_INFO("Receive create transmission request with id [{}]",
transmission_id_); transmission_id);
if (transmission_list_.find(transmission_id_) == if (transmission_list_.find(transmission_id) ==
transmission_list_.end()) { transmission_list_.end()) {
if (transmission_id_.empty()) { if (transmission_id.empty()) {
transmission_id_ = gen_random_6(); transmission_id = GenerateTransmissionId();
while (transmission_list_.find(transmission_id_) != while (transmission_list_.find(transmission_id) !=
transmission_list_.end()) { transmission_list_.end()) {
transmission_id_ = gen_random_6(); transmission_id = GenerateTransmissionId();
} }
LOG_INFO( LOG_INFO(
"Transmission id is empty, generate a new one for this request " "Transmission id is empty, generate a new one for this request "
"[{}]", "[{}]",
transmission_id_); transmission_id);
} }
transmission_list_.insert(transmission_id_); transmission_list_.insert(transmission_id);
LOG_INFO("Create transmission id [{}]", transmission_id_); transmission_manager_.BindHostToTransmission(hdl, transmission_id);
LOG_INFO("Create transmission id [{}]", transmission_id);
json message = {{"type", "transmission_id"}, json message = {{"type", "transmission_id"},
{"transmission_id", transmission_id_}, {"transmission_id", transmission_id},
{"status", "success"}}; {"status", "success"}};
send_msg(hdl, message); send_msg(hdl, message);
} else { } else {
LOG_INFO("Transmission id [{}] already exist", transmission_id_); LOG_INFO("Transmission id [{}] already exist", transmission_id);
json message = {{"type", "transmission_id"}, json message = {{"type", "transmission_id"},
{"transmission_id", transmission_id_}, {"transmission_id", transmission_id},
{"status", "fail"}, {"status", "fail"},
{"reason", "Transmission id exist"}}; {"reason", "Transmission id exist"}};
send_msg(hdl, message); send_msg(hdl, message);
@@ -140,49 +131,52 @@ void SignalServer::on_message(websocketpp::connection_hdl hdl,
break; break;
} }
case "offer"_H: { case "offer"_H: {
std::string transmission_id = j["transmission_id"]; std::string transmission_id = j["transmission_id"].get<std::string>();
std::string sdp = j["sdp"]; std::string sdp = j["sdp"].get<std::string>();
LOG_INFO("Save transmission_id[{}] with offer sdp[{}]", transmission_id, LOG_INFO("Receive transmission id [{}] with offer sdp [{}]",
sdp); transmission_id, sdp);
// ws_handle_manager_.BindHandleToConnection(hdl, ); transmission_manager_.BindGuestToTransmission(hdl, transmission_id);
offer_sdp_map_[transmission_id] = sdp;
offer_hdl_map_[transmission_id] = hdl; websocketpp::connection_hdl host_hdl =
break; transmission_manager_.GetHostOfTransmission(transmission_id);
}
case "query_remote_sdp"_H: { std::string ice_username = GetIceUsername(sdp);
std::string transmission_id = j["transmission_id"]; transmission_manager_.BindGuestUsernameToWsHandle(ice_username, hdl);
std::string sdp = offer_sdp_map_[transmission_id];
LOG_INFO("send offer sdp [{}]", sdp.c_str()); LOG_INFO("send offer sdp [{}]", sdp.c_str());
json message = {{"type", "remote_sdp"}, {"sdp", sdp}}; json message = {{"type", "offer"}, {"sdp", sdp}, {"guest", ice_username}};
send_msg(hdl, message); send_msg(host_hdl, message);
break; break;
} }
case "answer"_H: { case "answer"_H: {
std::string transmission_id = j["transmission_id"]; std::string transmission_id = j["transmission_id"].get<std::string>();
std::string sdp = j["sdp"]; std::string sdp = j["sdp"].get<std::string>();
LOG_INFO("Save transmission_id[{}] with answer sdp[{}]", transmission_id, std::string guest_ice_username = j["guest"].get<std::string>();
sdp); LOG_INFO("Receive transmission id [{}] with answer sdp [{}]",
answer_sdp_map_[transmission_id] = sdp; transmission_id, sdp);
answer_hdl_map_[transmission_id] = hdl;
websocketpp::connection_hdl guest_hdl =
transmission_manager_.GetGuestWsHandle(guest_ice_username);
LOG_INFO("send answer sdp [{}]", sdp.c_str()); LOG_INFO("send answer sdp [{}]", sdp.c_str());
json message = {{"type", "remote_sdp"}, {"sdp", sdp}}; json message = {{"type", "remote_sdp"}, {"sdp", sdp}};
send_msg(offer_hdl_map_[transmission_id], message); send_msg(guest_hdl, message);
break; break;
} }
case "offer_candidate"_H: { case "offer_candidate"_H: {
std::string transmission_id = j["transmission_id"]; std::string transmission_id = j["transmission_id"].get<std::string>();
std::string candidate = j["sdp"]; std::string candidate = j["sdp"].get<std::string>();
LOG_INFO("send candidate [{}]", candidate.c_str()); LOG_INFO("send candidate [{}]", candidate.c_str());
json message = {{"type", "candidate"}, {"sdp", candidate}}; json message = {{"type", "candidate"}, {"sdp", candidate}};
send_msg(answer_hdl_map_[transmission_id], message); // send_msg(answer_hdl_map_[transmission_id], message);
break; break;
} }
case "answer_candidate"_H: { case "answer_candidate"_H: {
std::string transmission_id = j["transmission_id"]; std::string transmission_id = j["transmission_id"].get<std::string>();
std::string candidate = j["sdp"]; std::string candidate = j["sdp"].get<std::string>();
LOG_INFO("send candidate [{}]", candidate.c_str()); LOG_INFO("send candidate [{}]", candidate.c_str());
json message = {{"type", "candidate"}, {"sdp", candidate}}; json message = {{"type", "candidate"}, {"sdp", candidate}};
send_msg(offer_hdl_map_[transmission_id], message); // send_msg(offer_hdl_map_[transmission_id], message);
break; break;
} }
default: default:

View File

@@ -9,8 +9,7 @@
#include <websocketpp/config/asio_no_tls.hpp> #include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/server.hpp> #include <websocketpp/server.hpp>
#include "sdp_manager.h" #include "transmission_manager.h"
#include "ws_handle_manager.h"
using nlohmann::json; using nlohmann::json;
@@ -31,7 +30,7 @@ class SignalServer {
bool on_pong(websocketpp::connection_hdl hdl, std::string s); bool on_pong(websocketpp::connection_hdl hdl, std::string s);
void run(); void run(uint16_t port);
void on_message(websocketpp::connection_hdl hdl, server::message_ptr msg); void on_message(websocketpp::connection_hdl hdl, server::message_ptr msg);
@@ -44,17 +43,9 @@ class SignalServer {
ws_connections_; ws_connections_;
std::map<room_id, connection_id> rooms_; std::map<room_id, connection_id> rooms_;
unsigned int ws_connection_id_ = 0; unsigned int ws_connection_id_ = 0;
std::string transmission_id_ = "000000";
std::set<std::string> transmission_list_; std::set<std::string> transmission_list_;
TransmissionManager transmission_manager_;
std::map<std::string, std::string> offer_sdp_map_;
std::map<std::string, std::string> answer_sdp_map_;
std::map<std::string, websocketpp::connection_hdl> offer_hdl_map_;
std::map<std::string, websocketpp::connection_hdl> answer_hdl_map_;
WsHandleManager ws_handle_manager_;
SdpManager sdp_manager_;
}; };
#endif #endif

View File

@@ -0,0 +1,80 @@
#include "transmission_manager.h"
#include "log.h"
TransmissionManager::TransmissionManager() {}
TransmissionManager::~TransmissionManager() {}
bool TransmissionManager::BindHostToTransmission(
websocketpp::connection_hdl hdl, const std::string& transmission_id) {
if (transmission_host_list_.find(transmission_id) !=
transmission_host_list_.end()) {
LOG_WARN("Transmission already has a host [{}]",
transmission_host_list_[transmission_id].lock().get());
return false;
} else {
transmission_host_list_[transmission_id] = hdl;
}
return true;
}
bool TransmissionManager::BindGuestToTransmission(
websocketpp::connection_hdl hdl, const std::string& transmission_id) {
return true;
}
bool TransmissionManager::ReleaseHostFromTransmission(
websocketpp::connection_hdl hdl, const std::string& transmission_id) {
return true;
}
bool TransmissionManager::ReleaseGuestFromTransmission(
websocketpp::connection_hdl hdl, const std::string& transmission_id) {
return true;
}
bool TransmissionManager::BindGuestUsernameToWsHandle(
const std::string& guest_username, websocketpp::connection_hdl hdl) {
if (transmission_guest_username_list_.find(guest_username) !=
transmission_guest_username_list_.end()) {
LOG_WARN("Guest already bind to username [{}]", guest_username.c_str());
return false;
} else {
transmission_guest_username_list_[guest_username] = hdl;
}
return true;
}
websocketpp::connection_hdl TransmissionManager::GetHostOfTransmission(
const std::string& transmission_id) {
if (transmission_host_list_.find(transmission_id) !=
transmission_host_list_.end()) {
return transmission_host_list_[transmission_id];
} else {
websocketpp::connection_hdl hdl;
return hdl;
}
}
std::set<websocketpp::connection_hdl>
TransmissionManager::GetGuestOfTransmission(
const std::string& transmission_id) {
if (transmission_guest_list_.find(transmission_id) !=
transmission_guest_list_.end()) {
return transmission_guest_list_[transmission_id];
} else {
return std::set<websocketpp::connection_hdl>();
}
}
websocketpp::connection_hdl TransmissionManager::GetGuestWsHandle(
const std::string& guest_username) {
if (transmission_guest_username_list_.find(guest_username) !=
transmission_guest_username_list_.end()) {
return transmission_guest_username_list_[guest_username];
} else {
websocketpp::connection_hdl hdl;
return hdl;
}
}

View File

@@ -0,0 +1,42 @@
#ifndef _TRANSIMISSION_MANAGER_H_
#define _TRANSIMISSION_MANAGER_H_
#include <map>
#include <set>
#include <websocketpp/server.hpp>
class TransmissionManager {
public:
TransmissionManager();
~TransmissionManager();
public:
bool BindHostToTransmission(websocketpp::connection_hdl hdl,
const std::string& transmission_id);
bool BindGuestToTransmission(websocketpp::connection_hdl hdl,
const std::string& transmission_id);
bool ReleaseHostFromTransmission(websocketpp::connection_hdl hdl,
const std::string& transmission_id);
bool ReleaseGuestFromTransmission(websocketpp::connection_hdl hdl,
const std::string& transmission_id);
bool BindGuestUsernameToWsHandle(const std::string& guest_username,
websocketpp::connection_hdl hdl);
websocketpp::connection_hdl GetHostOfTransmission(
const std::string& transmission_id);
std::set<websocketpp::connection_hdl> GetGuestOfTransmission(
const std::string& transmission_id);
websocketpp::connection_hdl GetGuestWsHandle(
const std::string& guest_username);
private:
std::map<std::string, websocketpp::connection_hdl> transmission_host_list_;
std::map<std::string, std::set<websocketpp::connection_hdl>>
transmission_guest_list_;
std::map<std::string, websocketpp::connection_hdl>
transmission_guest_username_list_;
};
#endif

View File

@@ -1,5 +0,0 @@
#include "ws_handle_manager.h"
WsHandleManager::WsHandleManager() {}
WsHandleManager::~WsHandleManager() {}

View File

@@ -1,24 +0,0 @@
#ifndef _WS_HANDLE_MANAGER_H_
#define _WS_HANDLE_MANAGER_H_
#include <iostream>
#include <websocketpp/server.hpp>
class WsHandleManager {
public:
WsHandleManager();
~WsHandleManager();
public:
bool BindHandleToConnection(websocketpp::connection_hdl hdl,
std::string& connection_id);
bool ReleaseHandleFromConnection(websocketpp::connection_hdl hdl,
std::string& connection_id);
const std::string& GetConnectionId(websocketpp::connection_hdl hdl);
websocketpp::connection_hdl GetWsHandle(std::string& connection_id);
private:
};
#endif

View File

@@ -32,6 +32,10 @@ target("log")
add_headerfiles("src/log/log.h") add_headerfiles("src/log/log.h")
add_includedirs("src/log", {public = true}) add_includedirs("src/log", {public = true})
target("common")
set_kind("headeronly")
add_includedirs("src/common", {public = true})
target("inih") target("inih")
set_kind("static") set_kind("static")
add_files("src/inih/ini.c", "src/inih/INIReader.cpp") add_files("src/inih/ini.c", "src/inih/INIReader.cpp")
@@ -39,7 +43,7 @@ target("inih")
target("ice") target("ice")
set_kind("static") set_kind("static")
add_deps("log", "ws") add_deps("log", "common", "ws")
add_packages("asio", "nlohmann_json", "libjuice") add_packages("asio", "nlohmann_json", "libjuice")
add_files("src/ice/*.cpp") add_files("src/ice/*.cpp")
add_includedirs("src/ws") add_includedirs("src/ws")
@@ -55,7 +59,7 @@ target("ws")
target("pc") target("pc")
set_kind("static") set_kind("static")
add_deps("log") add_deps("log")
add_deps("ws", "ice", "inih") add_deps("ws", "ice", "inih", "common")
add_files("src/pc/*.cpp") add_files("src/pc/*.cpp")
add_packages("asio", "nlohmann_json") add_packages("asio", "nlohmann_json")
add_includedirs("src/ws", "src/ice") add_includedirs("src/ws", "src/ice")
@@ -73,7 +77,7 @@ target("projectx")
target("signal_server") target("signal_server")
set_kind("binary") set_kind("binary")
add_deps("log") add_deps("log", "common")
add_files("tests/signal_server/*.cpp") add_files("tests/signal_server/*.cpp")
add_packages("asio", "nlohmann_json", "spdlog") add_packages("asio", "nlohmann_json", "spdlog")
add_includedirs("thirdparty/websocketpp/include") add_includedirs("thirdparty/websocketpp/include")