Init project

This commit is contained in:
dijunkun
2023-07-13 14:17:34 +08:00
commit ef6a04dc97
120 changed files with 26696 additions and 0 deletions

124
src/ice/ice_agent.cpp Normal file
View File

@@ -0,0 +1,124 @@
#include "ice_agent.h"
#include <string.h>
#include <iostream>
#include "log.h"
IceAgent::IceAgent() {}
IceAgent::~IceAgent() {}
int IceAgent::CreateIceAgent(juice_cb_state_changed_t on_state_changed,
juice_cb_candidate_t on_candidate,
juice_cb_gathering_done_t on_gathering_done,
juice_cb_recv_t on_recv, void *user_ptr) {
// juice_set_log_level(JUICE_LOG_LEVEL_DEBUG);
juice_config_t config;
memset(&config, 0, sizeof(config));
// STUN server example
config.stun_server_host = "120.77.216.215";
config.stun_server_port = 3478;
config.cb_state_changed = on_state_changed;
config.cb_candidate = on_candidate;
config.cb_gathering_done = on_gathering_done;
config.cb_recv = on_recv;
config.user_ptr = user_ptr;
agent_ = juice_create(&config);
return 0;
}
int IceAgent::DestoryIceAgent() {
juice_destroy(agent_);
return 0;
}
char *IceAgent::GenerateLocalSdp() {
if (nullptr == agent_) {
LOG_INFO("agent_ is nullptr");
return nullptr;
}
juice_get_local_description(agent_, local_sdp_, JUICE_MAX_SDP_STRING_LEN);
LOG_INFO("Generate local sdp:[\n{}]", local_sdp_);
return local_sdp_;
}
int IceAgent::SetRemoteSdp(const char *remote_sdp) {
LOG_INFO("Set remote sdp");
juice_set_remote_description(agent_, remote_sdp);
LOG_INFO("Remote description:[\n{}]", remote_sdp);
return 0;
}
int IceAgent::GatherCandidates() {
LOG_INFO("Gather candidates");
juice_gather_candidates(agent_);
return 0;
}
juice_state_t IceAgent::GetIceState() {
state_ = juice_get_state(agent_);
return state_;
}
bool IceAgent::GetSelectedCandidates() {
char local[JUICE_MAX_CANDIDATE_SDP_STRING_LEN];
char remote[JUICE_MAX_CANDIDATE_SDP_STRING_LEN];
bool success = state_ == JUICE_STATE_COMPLETED;
if (success &= (juice_get_selected_candidates(
agent_, local, JUICE_MAX_CANDIDATE_SDP_STRING_LEN, remote,
JUICE_MAX_CANDIDATE_SDP_STRING_LEN) == 0)) {
LOG_INFO("Local candidate 1: {}", local);
LOG_INFO("Remote candidate 1: {}", remote);
if ((!strstr(local, "typ host") && !strstr(local, "typ prflx")) ||
(!strstr(remote, "typ host") && !strstr(remote, "typ prflx")))
success = false; // local connection should be possible
}
return success;
}
bool IceAgent::GetSelectedAddresses() {
char localAddr[JUICE_MAX_ADDRESS_STRING_LEN];
char remoteAddr[JUICE_MAX_ADDRESS_STRING_LEN];
bool success = state_ == JUICE_STATE_COMPLETED;
if (success &= (juice_get_selected_addresses(
agent_, localAddr, JUICE_MAX_ADDRESS_STRING_LEN,
remoteAddr, JUICE_MAX_ADDRESS_STRING_LEN) == 0)) {
LOG_INFO("Local address 1: {}", localAddr);
LOG_INFO("Remote address 1: {}", remoteAddr);
}
return success;
}
int IceAgent::AddRemoteCandidates(const char *remote_candidates) {
juice_add_remote_candidate(agent_, remote_candidates);
return 0;
}
int IceAgent::SetRemoteGatheringDone() {
juice_set_remote_gathering_done(agent_);
return 0;
}
int IceAgent::Send(const char *data, size_t size) {
juice_send(agent_, data, size);
return 0;
}

42
src/ice/ice_agent.h Normal file
View File

@@ -0,0 +1,42 @@
#ifndef _ICE_AGENT_H_
#define _ICE_AGENT_H_
#include "juice/juice.h"
class IceAgent {
public:
IceAgent();
~IceAgent();
int CreateIceAgent(juice_cb_state_changed_t on_state_changed,
juice_cb_candidate_t on_candidate,
juice_cb_gathering_done_t on_gathering_done,
juice_cb_recv_t on_recv, void* user_ptr);
int DestoryIceAgent();
char* GenerateLocalSdp();
int SetRemoteSdp(const char* remote_sdp);
int GatherCandidates();
juice_state_t GetIceState();
bool GetSelectedCandidates();
bool GetSelectedAddresses();
int AddRemoteCandidates(const char* remote_candidates);
int SetRemoteGatheringDone();
int Send(const char* data, size_t size);
private:
juice_agent_t* agent_ = nullptr;
char local_sdp_[JUICE_MAX_SDP_STRING_LEN];
juice_state_t state_;
};
#endif

267
src/ice/ice_transport.cpp Normal file
View File

@@ -0,0 +1,267 @@
#include "ice_transport.h"
#include <map>
#include <nlohmann/json.hpp>
#include "log.h"
using nlohmann::json;
static const std::map<std::string, unsigned int> siganl_types{
{"connection_id", 1},
{"offer", 2},
{"transport_id", 3},
{"remote_sdp", 4},
{"candidate", 5}};
const std::vector<std::string> ice_status = {
"JUICE_STATE_DISCONNECTED", "JUICE_STATE_GATHERING",
"JUICE_STATE_CONNECTING", "JUICE_STATE_CONNECTED",
"JUICE_STATE_COMPLETED", "JUICE_STATE_FAILED"};
IceTransport::IceTransport(
WsTransport *ice_ws_transport,
std::function<void(const char *, size_t)> on_receive_ice_msg)
: ice_ws_transport_(ice_ws_transport),
on_receive_ice_msg_cb_(on_receive_ice_msg) {}
IceTransport::~IceTransport() {}
int IceTransport::InitIceTransport() {
ice_agent_ = new IceAgent();
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<IceTransport
// *>(user_ptr)->SendOfferLocalCandidate(sdp);
},
[](juice_agent_t *agent, void *user_ptr) {
LOG_INFO("gather_done");
// non-trickle
if (user_ptr) {
static_cast<IceTransport *>(user_ptr)->GetLocalSdp();
static_cast<IceTransport *>(user_ptr)->SendOffer();
}
},
[](juice_agent_t *agent, const char *data, size_t size, void *user_ptr) {
LOG_INFO("on_recv");
if (user_ptr &&
static_cast<IceTransport *>(user_ptr)->on_receive_ice_msg_cb_) {
static_cast<IceTransport *>(user_ptr)->on_receive_ice_msg_cb_(data,
size);
}
},
this);
return 0;
}
int IceTransport::InitIceTransport(std::string const &id) {
transport_id_ = id;
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<IceTransport *>(user_ptr)->CreateAnswer();
static_cast<IceTransport *>(user_ptr)->SendAnswer();
}
},
[](juice_agent_t *agent, const char *data, size_t size, void *user_ptr) {
LOG_INFO("on_recv");
if (user_ptr &&
static_cast<IceTransport *>(user_ptr)->on_receive_ice_msg_cb_) {
static_cast<IceTransport *>(user_ptr)->on_receive_ice_msg_cb_(data,
size);
}
},
this);
return 0;
}
int IceTransport::DestroyIceTransport() {
if (ice_agent_) {
delete ice_agent_;
}
return 0;
}
int IceTransport::CreateTransport() {
LOG_INFO("Create transport");
offer_peer_ = true;
// if (SignalStatus::Connected != signal_status_) {
// LOG_ERROR("Not connect to signalserver");
// return -1;
// }
json message = {{"type", "create_transport"}};
if (ice_ws_transport_) {
ice_ws_transport_->Send(message.dump());
LOG_INFO("Send msg: {}", message.dump().c_str());
}
CreateOffer();
return 0;
}
int IceTransport::CreateTransport(std::string transport_id) {
LOG_INFO("Join transport");
offer_peer_ = false;
// if (SignalStatus::Connected != signal_status_) {
// LOG_ERROR("Not connect to signalserver");
// return -1;
// }
QueryRemoteSdp(transport_id);
return 0;
}
int IceTransport::GatherCandidates() {
ice_agent_->GatherCandidates();
return 0;
}
int IceTransport::GetLocalSdp() {
local_sdp_ = ice_agent_->GenerateLocalSdp();
return 0;
}
int IceTransport::SetRemoteSdp(const std::string &remote_sdp) {
ice_agent_->SetRemoteSdp(remote_sdp.c_str());
return 0;
}
int IceTransport::AddRemoteCandidate(const std::string &remote_candidate) {
ice_agent_->AddRemoteCandidates(remote_candidate.c_str());
return 0;
}
int IceTransport::CreateOffer() {
LOG_INFO("Create offer");
GatherCandidates();
return 0;
}
int IceTransport::SendOffer() {
json message = {
{"type", "offer"}, {"transport_id", transport_id_}, {"sdp", local_sdp_}};
LOG_INFO("Send offer:\n{}", message.dump().c_str());
if (ice_ws_transport_) {
ice_ws_transport_->Send(message.dump());
}
return 0;
}
int IceTransport::QueryRemoteSdp(std::string transport_id) {
json message = {{"type", "query_remote_sdp"},
{"transport_id", transport_id_}};
LOG_INFO("Query remote sdp");
if (ice_ws_transport_) {
ice_ws_transport_->Send(message.dump());
}
return 0;
}
int IceTransport::CreateAnswer() {
GetLocalSdp();
return 0;
}
int IceTransport::SendAnswer() {
json message = {
{"type", "answer"}, {"transport_id", transport_id_}, {"sdp", local_sdp_}};
LOG_INFO("Send answer:\n{}", message.dump().c_str());
if (ice_ws_transport_) {
ice_ws_transport_->Send(message.dump());
}
return 0;
}
int IceTransport::SendOfferLocalCandidate(const std::string &remote_candidate) {
json message = {{"type", "offer_candidate"},
{"transport_id", transport_id_},
{"sdp", remote_candidate}};
LOG_INFO("Send candidate:\n{}", message.dump().c_str());
if (ice_ws_transport_) {
ice_ws_transport_->Send(message.dump());
}
return 0;
}
int IceTransport::SendAnswerLocalCandidate(
const std::string &remote_candidate) {
json message = {{"type", "answer_candidate"},
{"transport_id", transport_id_},
{"sdp", remote_candidate}};
LOG_INFO("Send candidate:\n{}", message.dump().c_str());
if (ice_ws_transport_) {
ice_ws_transport_->Send(message.dump());
}
return 0;
}
int IceTransport::SendData(const char *data, size_t size) {
ice_agent_->Send(data, size);
return 0;
}
void IceTransport::OnReceiveMessage(const std::string &msg) {
auto j = json::parse(msg);
LOG_INFO("msg: {}", msg.c_str());
std::string type = j["type"];
auto itr = siganl_types.find(type);
if (itr != siganl_types.end()) {
LOG_INFO("msg type :{}", itr->first);
switch (itr->second) {
case 2: {
break;
}
case 3: {
transport_id_ = j["transport_id"].get<std::string>();
LOG_INFO("Receive local peer transport_id [{}]", transport_id_);
// SendOffer();
break;
}
case 4: {
remote_sdp_ = j["sdp"].get<std::string>();
LOG_INFO("Receive remote sdp [{}]", remote_sdp_);
SetRemoteSdp(remote_sdp_);
if (!offer_peer_) {
GatherCandidates();
}
break;
}
case 5: {
std::string candidate = j["sdp"].get<std::string>();
LOG_INFO("Receive candidate [{}]", candidate);
AddRemoteCandidate(candidate);
break;
}
default:
break;
}
}
}

66
src/ice/ice_transport.h Normal file
View File

@@ -0,0 +1,66 @@
#ifndef _ICE_TRANSPORT_H_
#define _ICE_TRANSPORT_H_
#include <iostream>
#include "ice_agent.h"
#include "ws_transport.h"
class IceTransport {
public:
IceTransport(WsTransport *ice_ws_transport,
std::function<void(const char *, size_t)> on_receive_ice_msg);
~IceTransport();
int InitIceTransport();
int InitIceTransport(std::string const &id);
int DestroyIceTransport();
int CreateTransport();
int CreateTransport(std::string transport_id);
int SendData(const char *data, size_t size);
void OnReceiveUserData(const char *data, size_t size);
void OnReceiveMessage(const std::string &msg);
private:
int GatherCandidates();
int GetLocalSdp();
int QueryRemoteSdp(std::string transport_id);
int SetRemoteSdp(const std::string &remote_sdp);
int AddRemoteCandidate(const std::string &remote_candidate);
int CreateOffer();
int SendOffer();
int CreateAnswer();
int SendAnswer();
int SendOfferLocalCandidate(const std::string &remote_candidate);
int SendAnswerLocalCandidate(const std::string &remote_candidate);
private:
IceAgent *ice_agent_ = nullptr;
WsTransport *ice_ws_transport_ = nullptr;
std::function<void(const char *, size_t)> on_receive_ice_msg_cb_ = nullptr;
std::string local_sdp_;
std::string remote_sdp_;
std::string local_candidates_;
std::string remote_candidates_;
unsigned int connection_id_ = 0;
std::string transport_id_ = "";
bool offer_peer_ = true;
};
#endif

127
src/log/log.h Normal file
View File

@@ -0,0 +1,127 @@
#ifndef _LOG_H_
#define _LOG_H_
#include <chrono>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
#include "spdlog/common.h"
#include "spdlog/logger.h"
#include "spdlog/sinks/base_sink.h"
#include "spdlog/sinks/rotating_file_sink.h"
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/spdlog.h"
using namespace std::chrono;
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_INFO
// SPDLOG_TRACE(...)
// SPDLOG_DEBUG(...)
// SPDLOG_INFO(...)
// SPDLOG_WARN(...)
// SPDLOG_ERROR(...)
// SPDLOG_CRITICAL(...)
#ifdef SIGNAL_LOGGER
constexpr auto LOGGER_NAME = "siganl";
#else
constexpr auto LOGGER_NAME = "rtc";
#endif
#define LOG_INFO(...) \
if (nullptr == spdlog::get(LOGGER_NAME)) { \
auto now = std::chrono::system_clock::now() + std::chrono::hours(8); \
auto timet = std::chrono::system_clock::to_time_t(now); \
auto localTime = *std::gmtime(&timet); \
std::stringstream ss; \
std::string filename; \
ss << LOGGER_NAME; \
ss << std::put_time(&localTime, "-%Y%m%d-%H%M%S.log"); \
ss >> filename; \
std::string path = "logs/" + filename; \
std::vector<spdlog::sink_ptr> sinks; \
sinks.push_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>()); \
sinks.push_back(std::make_shared<spdlog::sinks::rotating_file_sink_mt>( \
path, 1048576 * 5, 3)); \
auto combined_logger = std::make_shared<spdlog::logger>( \
LOGGER_NAME, begin(sinks), end(sinks)); \
combined_logger->flush_on(spdlog::level::info); \
spdlog::register_logger(combined_logger); \
SPDLOG_LOGGER_INFO(combined_logger, __VA_ARGS__); \
} else { \
SPDLOG_LOGGER_INFO(spdlog::get(LOGGER_NAME), __VA_ARGS__); \
}
#define LOG_WARN(...) \
if (nullptr == spdlog::get(LOGGER_NAME)) { \
auto now = std::chrono::system_clock::now() + std::chrono::hours(8); \
auto timet = std::chrono::system_clock::to_time_t(now); \
auto localTime = *std::gmtime(&timet); \
std::stringstream ss; \
std::string filename; \
ss << LOGGER_NAME; \
ss << std::put_time(&localTime, "-%Y%m%d-%H%M%S.log"); \
ss >> filename; \
std::string path = "logs/" + filename; \
std::vector<spdlog::sink_ptr> sinks; \
sinks.push_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>()); \
sinks.push_back(std::make_shared<spdlog::sinks::rotating_file_sink_mt>( \
path, 1048576 * 5, 3)); \
auto combined_logger = std::make_shared<spdlog::logger>( \
LOGGER_NAME, begin(sinks), end(sinks)); \
spdlog::register_logger(combined_logger); \
SPDLOG_LOGGER_WARN(combined_logger, __VA_ARGS__); \
} else { \
SPDLOG_LOGGER_WARN(spdlog::get(LOGGER_NAME), __VA_ARGS__); \
}
#define LOG_ERROR(...) \
if (nullptr == spdlog::get(LOGGER_NAME)) { \
auto now = std::chrono::system_clock::now() + std::chrono::hours(8); \
auto timet = std::chrono::system_clock::to_time_t(now); \
auto localTime = *std::gmtime(&timet); \
std::stringstream ss; \
std::string filename; \
ss << LOGGER_NAME; \
ss << std::put_time(&localTime, "-%Y%m%d-%H%M%S.log"); \
ss >> filename; \
std::string path = "logs/" + filename; \
std::vector<spdlog::sink_ptr> sinks; \
sinks.push_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>()); \
sinks.push_back(std::make_shared<spdlog::sinks::rotating_file_sink_mt>( \
path, 1048576 * 5, 3)); \
auto combined_logger = std::make_shared<spdlog::logger>( \
LOGGER_NAME, begin(sinks), end(sinks)); \
spdlog::register_logger(combined_logger); \
SPDLOG_LOGGER_ERROR(combined_logger, __VA_ARGS__); \
} else { \
SPDLOG_LOGGER_ERROR(spdlog::get(LOGGER_NAME), __VA_ARGS__); \
}
#define LOG_FATAL(...) \
if (nullptr == spdlog::get(LOGGER_NAME)) { \
auto now = std::chrono::system_clock::now() + std::chrono::hours(8); \
auto timet = std::chrono::system_clock::to_time_t(now); \
auto localTime = *std::gmtime(&timet); \
std::stringstream ss; \
std::string filename; \
ss << LOGGER_NAME; \
ss << std::put_time(&localTime, "-%Y%m%d-%H%M%S.log"); \
ss >> filename; \
std::string path = "logs/" + filename; \
std::vector<spdlog::sink_ptr> sinks; \
sinks.push_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>()); \
sinks.push_back(std::make_shared<spdlog::sinks::rotating_file_sink_mt>( \
path, 1048576 * 5, 3)); \
auto combined_logger = std::make_shared<spdlog::logger>( \
LOGGER_NAME, begin(sinks), end(sinks)); \
spdlog::register_logger(combined_logger); \
SPDLOG_LOGGER_CRITICAL(combined_logger, __VA_ARGS__); \
} else { \
SPDLOG_LOGGER_CRITICAL(spdlog::get(LOGGER_NAME), __VA_ARGS__); \
}
#endif

113
src/pc/peer_connection.cpp Normal file
View File

@@ -0,0 +1,113 @@
#include "peer_connection.h"
#include <nlohmann/json.hpp>
#include "log.h"
using nlohmann::json;
static const std::map<std::string, unsigned int> siganl_types{
{"connection_id", 1},
{"offer", 2},
{"transport_id", 3},
{"remote_sdp", 4},
{"candidate", 5}};
PeerConnection::PeerConnection() {}
PeerConnection::~PeerConnection() {}
int PeerConnection::Init(std::string const &uri) {
on_receive_ws_msg_ = [this](const std::string &msg) {
do {
} while (!ice_transport_);
auto j = json::parse(msg);
std::string type = j["type"];
auto itr = siganl_types.find(type);
if (itr != siganl_types.end()) {
LOG_INFO("msg type :{}", itr->first);
switch (itr->second) {
case 1: {
connection_id_ = j["connection_id"].get<unsigned int>();
LOG_INFO("Receive local peer connection_id [{}]", connection_id_);
signal_status_ = SignalStatus::Connected;
break;
}
default: {
ice_transport_->OnReceiveMessage(msg);
break;
}
}
}
};
on_receive_ice_msg_ = [this](const char *data, size_t size) {};
ws_transport_ = new WsTransport(on_receive_ws_msg_);
if (ws_transport_) {
ws_transport_->Connect(uri);
}
ice_transport_ = new IceTransport(ws_transport_, on_receive_ice_msg_);
ice_transport_->InitIceTransport();
do {
LOG_INFO("GetSignalStatus = {}", GetSignalStatus());
} while (SignalStatus::Connected != GetSignalStatus());
ice_transport_->CreateTransport();
return 0;
}
int PeerConnection::Init(std::string const &uri, std::string const &id) {
on_receive_ws_msg_ = [this](const std::string &msg) {
do {
} while (!ice_transport_);
auto j = json::parse(msg);
std::string type = j["type"];
auto itr = siganl_types.find(type);
if (itr != siganl_types.end()) {
LOG_INFO("msg type :{}", itr->first);
switch (itr->second) {
case 1: {
connection_id_ = j["connection_id"].get<unsigned int>();
LOG_INFO("Receive local peer connection_id [{}]", connection_id_);
signal_status_ = SignalStatus::Connected;
break;
}
default: {
ice_transport_->OnReceiveMessage(msg);
break;
}
}
}
};
on_receive_ice_msg_ = [this](const char *data, size_t size) {};
transport_id_ = id;
ws_transport_ = new WsTransport(on_receive_ws_msg_);
if (ws_transport_) {
ws_transport_->Connect(uri);
}
ice_transport_ = new IceTransport(ws_transport_, on_receive_ice_msg_);
ice_transport_->InitIceTransport(id);
do {
LOG_INFO("GetSignalStatus = {}", GetSignalStatus());
} while (SignalStatus::Connected != GetSignalStatus());
ice_transport_->CreateTransport(transport_id_);
return 0;
}
int PeerConnection::Destroy() {
if (ws_transport_) {
delete ws_transport_;
}
return 0;
}
SignalStatus PeerConnection::GetSignalStatus() { return signal_status_; }

33
src/pc/peer_connection.h Normal file
View File

@@ -0,0 +1,33 @@
#ifndef _PEER_CONNECTION_H_
#define _PEER_CONNECTION_H_
#include <iostream>
#include "ice_transport.h"
#include "ws_transport.h"
enum SignalStatus { Connecting = 0, Connected, Closed };
class PeerConnection {
public:
PeerConnection();
~PeerConnection();
public:
int Init(std::string const &uri);
int Init(std::string const &uri, std::string const &id);
int Destroy();
SignalStatus GetSignalStatus();
private:
WsTransport *ws_transport_ = nullptr;
IceTransport *ice_transport_ = nullptr;
std::function<void(const std::string &)> on_receive_ws_msg_ = nullptr;
std::function<void(const char *, size_t)> on_receive_ice_msg_ = nullptr;
unsigned int connection_id_ = 0;
std::string transport_id_ = "";
SignalStatus signal_status_ = SignalStatus::Closed;
};
#endif

101
src/rtc/rtc.cpp Normal file
View File

@@ -0,0 +1,101 @@
#include "rtc.h"
#include <iostream>
#include <nlohmann/json.hpp>
#include "ice_agent.h"
#include "log.h"
#include "peer_connection.h"
#include "ws_transport.h"
using nlohmann::json;
static const std::vector<std::string> siganl_status = {"Connecting",
"Connected", "Closed"};
class WsSender : public WsCore {
public:
WsSender() {}
~WsSender() {}
void OnReceiveMessage(const std::string &msg) {
LOG_INFO("Receive msg: {}", msg);
}
};
static WsSender *ws_client;
static PeerConnection *peer_connection;
int CreatePeerConnection(const char *uri) {
peer_connection = new PeerConnection();
peer_connection->Init(uri);
// do {
// } while (SignalStatus::Connected != peer_connection->GetSignalStatus());
// LOG_INFO("Signal status: {}",
// siganl_status[peer_connection->GetSignalStatus()]);
// peer_connection->CreateTransport();
// peer_connection->CreateOffer();
return 0;
}
int CreatePeerConnectionWithID(const char *uri, const char *id) {
peer_connection = new PeerConnection();
peer_connection->Init(uri, id);
// do {
// } while (SignalStatus::Connected != peer_connection->GetSignalStatus());
// LOG_INFO("Signal status: {}",
// siganl_status[peer_connection->GetSignalStatus()]);
// peer_connection->CreateTransport(id);
return 0;
}
int rtc() {
ws_client = new WsSender();
return 0;
}
int CreateWsClient(const char *uri) {
ws_client->Connect(uri);
return 0;
}
int WsSendMsg(const char *message) {
ws_client->Send(message);
return 0;
}
// ws_status GetWsStatus()
// {
// std::string ws_status = ws_client->GetStatus();
// if ("Connecting" == ws_status)
// {
// return ws_status::WS_CONNECTING;
// }
// else if ("Open" == ws_status)
// {
// return ws_status::WS_OPEN;
// }
// else if ("Failed" == ws_status)
// {
// return ws_status::WS_FAILED;
// }
// else if ("Closed" == ws_status)
// {
// return ws_status::WS_CLOSED;
// }
// else
// {
// return ws_status::WS_UNKNOWN;
// }
// }

30
src/rtc/rtc.h Normal file
View File

@@ -0,0 +1,30 @@
#ifndef _RTC_H_
#define _RTC_H_
enum ws_status { WS_CONNECTING = 0, WS_OPEN, WS_FAILED, WS_CLOSED, WS_UNKNOWN };
#ifdef __cplusplus
extern "C" {
#endif
int CreatePeerConnection(const char* uri);
int CreatePeerConnectionWithID(const char* uri, const char* id);
int rtc();
int ConnectToServer(const char* uri);
int RegisterPeer();
int CreateWsClient(const char* uri);
int WsSendMsg(const char* message);
ws_status GetWsStatus();
#ifdef __cplusplus
}
#endif
#endif

136
src/ws/ws_core.cpp Normal file
View File

@@ -0,0 +1,136 @@
#include "ws_core.h"
#include <cstdlib>
#include <iostream>
#include <sstream>
#include "log.h"
WsCore::WsCore() {
m_endpoint_.clear_access_channels(websocketpp::log::alevel::all);
m_endpoint_.clear_error_channels(websocketpp::log::elevel::all);
m_endpoint_.init_asio();
m_endpoint_.start_perpetual();
m_thread_ = websocketpp::lib::make_shared<websocketpp::lib::thread>(
&client::run, &m_endpoint_);
}
WsCore::~WsCore() {
m_endpoint_.stop_perpetual();
if (GetStatus() != "Open") {
// Only close open connections
return;
}
websocketpp::lib::error_code ec;
m_endpoint_.close(connection_handle_, websocketpp::close::status::going_away,
"", ec);
if (ec) {
LOG_INFO("> Error closing connection {}", ec.message());
}
m_thread_->join();
}
int WsCore::Connect(std::string const &uri) {
websocketpp::lib::error_code ec;
client::connection_ptr con = m_endpoint_.get_connection(uri, ec);
connection_handle_ = con->get_handle();
if (ec) {
LOG_INFO("> Connect initialization error: {}", ec.message());
return -1;
}
con->set_open_handler(websocketpp::lib::bind(
&WsCore::OnOpen, this, &m_endpoint_, websocketpp::lib::placeholders::_1));
con->set_fail_handler(websocketpp::lib::bind(
&WsCore::OnFail, this, &m_endpoint_, websocketpp::lib::placeholders::_1));
con->set_close_handler(
websocketpp::lib::bind(&WsCore::OnClose, this, &m_endpoint_,
websocketpp::lib::placeholders::_1));
// con->set_ping_handler(websocketpp::lib::bind(
// &WsCore::on_ping,
// this,
// websocketpp::lib::placeholders::_1,
// websocketpp::lib::placeholders::_2
// ));
con->set_pong_handler(websocketpp::lib::bind(
&WsCore::OnPong, this, websocketpp::lib::placeholders::_1,
websocketpp::lib::placeholders::_2));
con->set_pong_timeout(1000);
con->set_pong_timeout_handler(websocketpp::lib::bind(
&WsCore::OnPongTimeout, this, websocketpp::lib::placeholders::_1,
websocketpp::lib::placeholders::_2));
con->set_message_handler(websocketpp::lib::bind(
&WsCore::OnMessage, this, websocketpp::lib::placeholders::_1,
websocketpp::lib::placeholders::_2));
m_endpoint_.connect(con);
return 0;
}
void WsCore::Close(websocketpp::close::status::value code, std::string reason) {
websocketpp::lib::error_code ec;
m_endpoint_.close(connection_handle_, code, reason, ec);
if (ec) {
LOG_INFO("> Error initiating close: {}", ec.message());
}
}
void WsCore::Send(std::string message) {
websocketpp::lib::error_code ec;
m_endpoint_.send(connection_handle_, message,
websocketpp::frame::opcode::text, ec);
if (ec) {
LOG_INFO("> Error sending message: {}", ec.message());
return;
}
}
void WsCore::Ping() {
websocketpp::lib::error_code ec;
std::string message = "ping";
m_endpoint_.ping(connection_handle_, message, ec);
if (ec) {
LOG_INFO("> Error sending ping");
return;
}
}
const std::string &WsCore::GetStatus() { return connection_status_; }
void WsCore::OnOpen(client *c, websocketpp::connection_hdl hdl) {
connection_status_ = "Open";
}
void WsCore::OnFail(client *c, websocketpp::connection_hdl hdl) {
connection_status_ = "Failed";
}
void WsCore::OnClose(client *c, websocketpp::connection_hdl hdl) {
connection_status_ = "Closed";
}
void WsCore::OnPong(websocketpp::connection_hdl, std::string msg) {}
void WsCore::OnPongTimeout(websocketpp::connection_hdl, std::string msg) {}
void WsCore::OnMessage(websocketpp::connection_hdl, client::message_ptr &msg) {
OnReceiveMessage(msg->get_payload());
}

54
src/ws/ws_core.h Normal file
View File

@@ -0,0 +1,54 @@
#ifndef _WS_CORE_H_
#define _WS_CORE_H_
#include <map>
#include <sstream>
#include <string>
#include "websocketpp/client.hpp"
#include "websocketpp/common/memory.hpp"
#include "websocketpp/common/thread.hpp"
#include "websocketpp/config/asio_no_tls_client.hpp"
typedef websocketpp::client<websocketpp::config::asio_client> client;
class WsCore {
public:
WsCore();
virtual ~WsCore();
int Connect(std::string const &uri);
void Close(websocketpp::close::status::value code, std::string reason);
void Send(std::string message);
void Ping();
const std::string &GetStatus();
// Callback
void OnOpen(client *c, websocketpp::connection_hdl hdl);
void OnFail(client *c, websocketpp::connection_hdl hdl);
void OnClose(client *c, websocketpp::connection_hdl hdl);
void OnPong(websocketpp::connection_hdl, std::string msg);
void OnPongTimeout(websocketpp::connection_hdl, std::string msg);
void OnMessage(websocketpp::connection_hdl, client::message_ptr &msg);
virtual void OnReceiveMessage(const std::string &msg) = 0;
private:
client m_endpoint_;
websocketpp::connection_hdl connection_handle_;
websocketpp::lib::shared_ptr<websocketpp::lib::thread> m_thread_;
std::string connection_status_ = "Connecting";
};
#endif

16
src/ws/ws_transport.cpp Normal file
View File

@@ -0,0 +1,16 @@
#include "ws_transport.h"
#include "log.h"
WsTransport::WsTransport(
std::function<void(const std::string &)> on_receive_msg_cb)
: on_receive_msg_(on_receive_msg_cb) {}
WsTransport::~WsTransport() {}
void WsTransport::OnReceiveMessage(const std::string &msg) {
LOG_INFO("Receive msg: {}", msg);
if (on_receive_msg_) {
on_receive_msg_(msg);
}
}

18
src/ws/ws_transport.h Normal file
View File

@@ -0,0 +1,18 @@
#ifndef _WS_TRANSPORT_H_
#define _WS_TRANSPORT_H_
#include "ws_core.h"
class WsTransport : public WsCore {
public:
WsTransport(std::function<void(const std::string &)> on_receive_msg_cb);
~WsTransport();
public:
void OnReceiveMessage(const std::string &msg);
private:
std::function<void(const std::string &)> on_receive_msg_ = nullptr;
};
#endif