mirror of
				https://github.com/kunkundi/crossdesk.git
				synced 2025-10-26 20:25:34 +08:00 
			
		
		
		
	Support multiple ice connections
This commit is contained in:
		| @@ -1,6 +1,6 @@ | ||||
| [signal server] | ||||
| ip = localhost | ||||
| port = 9002 | ||||
| port = 9095 | ||||
|  | ||||
| [stun server] | ||||
| ip = 120.77.216.215 | ||||
|   | ||||
							
								
								
									
										33
									
								
								src/common/common.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/common/common.h
									
									
									
									
									
										Normal 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 | ||||
| @@ -4,31 +4,21 @@ | ||||
| #include <nlohmann/json.hpp> | ||||
| #include <thread> | ||||
|  | ||||
| #include "common.h" | ||||
| #include "log.h" | ||||
|  | ||||
| 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 = { | ||||
|     "JUICE_STATE_DISCONNECTED", "JUICE_STATE_GATHERING", | ||||
|     "JUICE_STATE_CONNECTING",   "JUICE_STATE_CONNECTED", | ||||
|     "JUICE_STATE_COMPLETED",    "JUICE_STATE_FAILED"}; | ||||
|  | ||||
| IceTransmission::IceTransmission( | ||||
|     WsTransmission *ice_ws_transmission, | ||||
|     bool offer_peer, WsTransmission *ice_ws_transmission, | ||||
|     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) {} | ||||
|  | ||||
| IceTransmission::~IceTransmission() {} | ||||
| @@ -50,43 +40,15 @@ int IceTransmission::InitIceTransmission(std::string &ip, int port) { | ||||
|         LOG_INFO("gather_done"); | ||||
|         // non-trickle | ||||
|         if (user_ptr) { | ||||
|           static_cast<IceTransmission *>(user_ptr)->GetLocalSdp(); | ||||
|           static_cast<IceTransmission *>(user_ptr)->SendOffer(); | ||||
|         } | ||||
|       }, | ||||
|       [](juice_agent_t *agent, const char *data, size_t size, void *user_ptr) { | ||||
|         if (user_ptr && | ||||
|             static_cast<IceTransmission *>(user_ptr)->on_receive_ice_msg_cb_) { | ||||
|           static_cast<IceTransmission *>(user_ptr)->on_receive_ice_msg_cb_( | ||||
|               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(); | ||||
|           IceTransmission *ice_transmission_obj = | ||||
|               static_cast<IceTransmission *>(user_ptr); | ||||
|           if (ice_transmission_obj->offer_peer_) { | ||||
|             ice_transmission_obj->GetLocalSdp(); | ||||
|             ice_transmission_obj->SendOffer(); | ||||
|           } else { | ||||
|             ice_transmission_obj->CreateAnswer(); | ||||
|             ice_transmission_obj->SendAnswer(); | ||||
|           } | ||||
|         } | ||||
|       }, | ||||
|       [](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) { | ||||
|   LOG_INFO("Create transport"); | ||||
|   offer_peer_ = true; | ||||
|   offer_peer_ = false; | ||||
|   transmission_id_ = transmission_id; | ||||
|  | ||||
|   // if (SignalStatus::Connected != signal_status_) { | ||||
|   //   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) { | ||||
|   LOG_INFO("Join transport"); | ||||
|   offer_peer_ = false; | ||||
|   offer_peer_ = true; | ||||
|   transmission_id_ = transmission_id; | ||||
|  | ||||
|   // if (SignalStatus::Connected != signal_status_) { | ||||
| @@ -154,6 +117,7 @@ int IceTransmission::GetLocalSdp() { | ||||
|  | ||||
| int IceTransmission::SetRemoteSdp(const std::string &remote_sdp) { | ||||
|   ice_agent_->SetRemoteSdp(remote_sdp.c_str()); | ||||
|   remote_ice_username_ = GetIceUsername(remote_sdp); | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| @@ -199,7 +163,8 @@ int IceTransmission::CreateAnswer() { | ||||
| int IceTransmission::SendAnswer() { | ||||
|   json message = {{"type", "answer"}, | ||||
|                   {"transmission_id", transmission_id_}, | ||||
|                   {"sdp", local_sdp_}}; | ||||
|                   {"sdp", local_sdp_}, | ||||
|                   {"guest", remote_ice_username_}}; | ||||
|   LOG_INFO("Send answer:\n{}", message.dump().c_str()); | ||||
|  | ||||
|   if (ice_ws_transport_) { | ||||
| @@ -247,6 +212,16 @@ void IceTransmission::OnReceiveMessage(const std::string &msg) { | ||||
|  | ||||
|   switch (HASH_STRING_PIECE(type.c_str())) { | ||||
|     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; | ||||
|     } | ||||
|     case "transmission_id"_H: { | ||||
|   | ||||
| @@ -8,13 +8,12 @@ | ||||
|  | ||||
| class IceTransmission { | ||||
|  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); | ||||
|  | ||||
|   ~IceTransmission(); | ||||
|  | ||||
|   int InitIceTransmission(std::string &ip, int port); | ||||
|   int InitIceTransmission(std::string &ip, int port, std::string const &id); | ||||
|  | ||||
|   int DestroyIceTransmission(); | ||||
|  | ||||
| @@ -27,7 +26,7 @@ class IceTransmission { | ||||
|  | ||||
|   void OnReceiveMessage(const std::string &msg); | ||||
|  | ||||
|  private: | ||||
|  public: | ||||
|   int GatherCandidates(); | ||||
|  | ||||
|   int GetLocalSdp(); | ||||
| @@ -56,6 +55,7 @@ class IceTransmission { | ||||
|   std::function<void(const char *, size_t)> on_receive_ice_msg_cb_ = nullptr; | ||||
|   std::string local_sdp_; | ||||
|   std::string remote_sdp_; | ||||
|   std::string remote_ice_username_; | ||||
|   std::string local_candidates_; | ||||
|   std::string remote_candidates_; | ||||
|   unsigned int connection_id_ = 0; | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
| #include <regex> | ||||
|  | ||||
| #include "INIReader.h" | ||||
| #include "common.h" | ||||
| #include "log.h" | ||||
| #include "nlohmann/json.hpp" | ||||
|  | ||||
| @@ -19,40 +20,69 @@ 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); | ||||
|   std::string cfg_signal_server_ip = reader.Get("signal server", "ip", "-1"); | ||||
|   std::string cfg_signal_server_port = | ||||
|       reader.Get("signal server", "port", "-1"); | ||||
|   std::string cfg_stun_server_ip = reader.Get("stun server", "ip", "-1"); | ||||
|   std::string cfg_stun_server_port = reader.Get("stun server", "port", "-1"); | ||||
|   cfg_signal_server_ip_ = reader.Get("signal server", "ip", "-1"); | ||||
|   cfg_signal_server_port_ = reader.Get("signal server", "port", "-1"); | ||||
|   cfg_stun_server_ip_ = reader.Get("stun server", "ip", "-1"); | ||||
|   cfg_stun_server_port_ = reader.Get("stun server", "port", "-1"); | ||||
|   std::regex regex("\n"); | ||||
|  | ||||
|   LOG_INFO("Read config success"); | ||||
|  | ||||
|   int signal_server_port = stoi(cfg_signal_server_port); | ||||
|   int stun_server_port = stoi(cfg_stun_server_port); | ||||
|   signal_server_port_ = stoi(cfg_signal_server_port_); | ||||
|   stun_server_port_ = stoi(cfg_stun_server_port_); | ||||
|  | ||||
|   on_receive_ws_msg_ = [this](const std::string &msg) { | ||||
|     do { | ||||
|     } while (!ice_transmission_); | ||||
|     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: { | ||||
|           ws_connection_id_ = j["ws_connection_id"].get<unsigned int>(); | ||||
|           LOG_INFO("Receive local peer websocket connection id [{}]", | ||||
|                    ws_connection_id_); | ||||
|           signal_status_ = SignalStatus::Connected; | ||||
|           break; | ||||
|     LOG_INFO("msg type :{}", type.c_str()); | ||||
|     switch (HASH_STRING_PIECE(type.c_str())) { | ||||
|       case "ws_connection_id"_H: { | ||||
|         ws_connection_id_ = j["ws_connection_id"].get<unsigned int>(); | ||||
|         LOG_INFO("Receive local peer websocket connection id [{}]", | ||||
|                  ws_connection_id_); | ||||
|         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: { | ||||
|           ice_transmission_->OnReceiveMessage(msg); | ||||
|           break; | ||||
|         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_); | ||||
|   uri_ = "ws://" + cfg_signal_server_ip + ":" + cfg_signal_server_port; | ||||
|   uri_ = "ws://" + cfg_signal_server_ip_ + ":" + cfg_signal_server_port_; | ||||
|   if (ws_transport_) { | ||||
|     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 { | ||||
|     LOG_INFO("GetSignalStatus = {}", 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; | ||||
| } | ||||
|  | ||||
| int PeerConnection::Join(PeerConnectionParams params, const std::string &id) { | ||||
| int PeerConnection::Join(PeerConnectionParams params, | ||||
|                          const std::string &transmission_id) { | ||||
|   INIReader reader(params.cfg_path); | ||||
|   std::string cfg_signal_server_ip = reader.Get("signal server", "ip", "-1"); | ||||
|   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()); | ||||
|   }; | ||||
|  | ||||
|   transmission_id_ = id; | ||||
|   transmission_id_ = transmission_id; | ||||
|  | ||||
|   ws_transport_ = new WsTransmission(on_receive_ws_msg_); | ||||
|   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_); | ||||
|   } | ||||
|  | ||||
|   ice_transmission_ = new IceTransmission(ws_transport_, on_receive_ice_msg_); | ||||
|   ice_transmission_->InitIceTransmission(cfg_stun_server_ip, stun_server_port, | ||||
|                                          id); | ||||
|   ice_transmission_ = | ||||
|       new IceTransmission(true, ws_transport_, on_receive_ice_msg_); | ||||
|   ice_transmission_->InitIceTransmission(cfg_stun_server_ip, stun_server_port); | ||||
|  | ||||
|   do { | ||||
|     LOG_INFO("GetSignalStatus = {}", GetSignalStatus()); | ||||
|   | ||||
| @@ -2,6 +2,7 @@ | ||||
| #define _PEER_CONNECTION_H_ | ||||
|  | ||||
| #include <iostream> | ||||
| #include <map> | ||||
|  | ||||
| #include "ice_transmission.h" | ||||
| #include "ws_transmission.h" | ||||
| @@ -35,8 +36,15 @@ class PeerConnection { | ||||
|  | ||||
|  private: | ||||
|   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; | ||||
|   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 char *, size_t)> on_receive_ice_msg_ = nullptr; | ||||
|   unsigned int ws_connection_id_ = 0; | ||||
|   | ||||
| @@ -1,8 +1,12 @@ | ||||
|  | ||||
| #include <iostream> | ||||
|  | ||||
| #include "signal_server.h" | ||||
|  | ||||
| int main() { | ||||
|     SignalServer s; | ||||
|     // connect ws://localhost:9002 | ||||
|     s.run(); | ||||
|     return 0; | ||||
| int main(int argc, char* argv[]) { | ||||
|   SignalServer s; | ||||
|   std::string port = argv[1]; | ||||
|   std::cout << "Port: " << port << std::endl; | ||||
|   s.run(std::stoi(port)); | ||||
|   return 0; | ||||
| } | ||||
| @@ -1,6 +0,0 @@ | ||||
|  | ||||
| #include "sdp_manager.h" | ||||
|  | ||||
| SdpManager ::SdpManager() {} | ||||
|  | ||||
| SdpManager ::~SdpManager() {} | ||||
| @@ -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 | ||||
| @@ -1,20 +1,9 @@ | ||||
| #include "signal_server.h" | ||||
|  | ||||
| #include "common.h" | ||||
| #include "log.h" | ||||
|  | ||||
| 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::string gen_random_6() { | ||||
| const std::string GenerateTransmissionId() { | ||||
|   static const char alphanum[] = "0123456789"; | ||||
|   std::string random_id; | ||||
|   random_id.reserve(6); | ||||
| @@ -65,7 +54,7 @@ bool SignalServer::on_open(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); | ||||
|   return true; | ||||
| } | ||||
| @@ -82,9 +71,9 @@ bool SignalServer::on_pong(websocketpp::connection_hdl hdl, std::string s) { | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| void SignalServer::run() { | ||||
|   // Listen on port 9002 | ||||
|   server_.listen(9002); | ||||
| void SignalServer::run(uint16_t port) { | ||||
|   // Listen on port 9093 | ||||
|   server_.listen(port); | ||||
|  | ||||
|   // Queues a connection accept operation | ||||
|   server_.start_accept(); | ||||
| @@ -102,36 +91,38 @@ void SignalServer::on_message(websocketpp::connection_hdl hdl, | ||||
|   std::string payload = msg->get_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())) { | ||||
|     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 [{}]", | ||||
|                transmission_id_); | ||||
|       if (transmission_list_.find(transmission_id_) == | ||||
|                transmission_id); | ||||
|       if (transmission_list_.find(transmission_id) == | ||||
|           transmission_list_.end()) { | ||||
|         if (transmission_id_.empty()) { | ||||
|           transmission_id_ = gen_random_6(); | ||||
|           while (transmission_list_.find(transmission_id_) != | ||||
|         if (transmission_id.empty()) { | ||||
|           transmission_id = GenerateTransmissionId(); | ||||
|           while (transmission_list_.find(transmission_id) != | ||||
|                  transmission_list_.end()) { | ||||
|             transmission_id_ = gen_random_6(); | ||||
|             transmission_id = GenerateTransmissionId(); | ||||
|           } | ||||
|           LOG_INFO( | ||||
|               "Transmission id is empty, generate a new one for this request " | ||||
|               "[{}]", | ||||
|               transmission_id_); | ||||
|               transmission_id); | ||||
|         } | ||||
|         transmission_list_.insert(transmission_id_); | ||||
|         LOG_INFO("Create transmission id [{}]", transmission_id_); | ||||
|         transmission_list_.insert(transmission_id); | ||||
|         transmission_manager_.BindHostToTransmission(hdl, transmission_id); | ||||
|  | ||||
|         LOG_INFO("Create transmission id [{}]", transmission_id); | ||||
|         json message = {{"type", "transmission_id"}, | ||||
|                         {"transmission_id", transmission_id_}, | ||||
|                         {"transmission_id", transmission_id}, | ||||
|                         {"status", "success"}}; | ||||
|         send_msg(hdl, message); | ||||
|       } else { | ||||
|         LOG_INFO("Transmission id [{}] already exist", transmission_id_); | ||||
|         LOG_INFO("Transmission id [{}] already exist", transmission_id); | ||||
|         json message = {{"type", "transmission_id"}, | ||||
|                         {"transmission_id", transmission_id_}, | ||||
|                         {"transmission_id", transmission_id}, | ||||
|                         {"status", "fail"}, | ||||
|                         {"reason", "Transmission id exist"}}; | ||||
|         send_msg(hdl, message); | ||||
| @@ -140,49 +131,52 @@ void SignalServer::on_message(websocketpp::connection_hdl hdl, | ||||
|       break; | ||||
|     } | ||||
|     case "offer"_H: { | ||||
|       std::string transmission_id = j["transmission_id"]; | ||||
|       std::string sdp = j["sdp"]; | ||||
|       LOG_INFO("Save transmission_id[{}] with offer sdp[{}]", transmission_id, | ||||
|                sdp); | ||||
|       // ws_handle_manager_.BindHandleToConnection(hdl, ); | ||||
|       offer_sdp_map_[transmission_id] = sdp; | ||||
|       offer_hdl_map_[transmission_id] = hdl; | ||||
|       break; | ||||
|     } | ||||
|     case "query_remote_sdp"_H: { | ||||
|       std::string transmission_id = j["transmission_id"]; | ||||
|       std::string sdp = offer_sdp_map_[transmission_id]; | ||||
|       std::string transmission_id = j["transmission_id"].get<std::string>(); | ||||
|       std::string sdp = j["sdp"].get<std::string>(); | ||||
|       LOG_INFO("Receive transmission id [{}] with offer sdp [{}]", | ||||
|                transmission_id, sdp); | ||||
|       transmission_manager_.BindGuestToTransmission(hdl, transmission_id); | ||||
|  | ||||
|       websocketpp::connection_hdl host_hdl = | ||||
|           transmission_manager_.GetHostOfTransmission(transmission_id); | ||||
|  | ||||
|       std::string ice_username = GetIceUsername(sdp); | ||||
|       transmission_manager_.BindGuestUsernameToWsHandle(ice_username, hdl); | ||||
|  | ||||
|       LOG_INFO("send offer sdp [{}]", sdp.c_str()); | ||||
|       json message = {{"type", "remote_sdp"}, {"sdp", sdp}}; | ||||
|       send_msg(hdl, message); | ||||
|       json message = {{"type", "offer"}, {"sdp", sdp}, {"guest", ice_username}}; | ||||
|       send_msg(host_hdl, message); | ||||
|       break; | ||||
|     } | ||||
|     case "answer"_H: { | ||||
|       std::string transmission_id = j["transmission_id"]; | ||||
|       std::string sdp = j["sdp"]; | ||||
|       LOG_INFO("Save transmission_id[{}] with answer sdp[{}]", transmission_id, | ||||
|                sdp); | ||||
|       answer_sdp_map_[transmission_id] = sdp; | ||||
|       answer_hdl_map_[transmission_id] = hdl; | ||||
|       std::string transmission_id = j["transmission_id"].get<std::string>(); | ||||
|       std::string sdp = j["sdp"].get<std::string>(); | ||||
|       std::string guest_ice_username = j["guest"].get<std::string>(); | ||||
|       LOG_INFO("Receive transmission id [{}] with answer sdp [{}]", | ||||
|                transmission_id, sdp); | ||||
|  | ||||
|       websocketpp::connection_hdl guest_hdl = | ||||
|           transmission_manager_.GetGuestWsHandle(guest_ice_username); | ||||
|  | ||||
|       LOG_INFO("send answer sdp [{}]", sdp.c_str()); | ||||
|       json message = {{"type", "remote_sdp"}, {"sdp", sdp}}; | ||||
|       send_msg(offer_hdl_map_[transmission_id], message); | ||||
|       send_msg(guest_hdl, message); | ||||
|       break; | ||||
|     } | ||||
|     case "offer_candidate"_H: { | ||||
|       std::string transmission_id = j["transmission_id"]; | ||||
|       std::string candidate = j["sdp"]; | ||||
|       std::string transmission_id = j["transmission_id"].get<std::string>(); | ||||
|       std::string candidate = j["sdp"].get<std::string>(); | ||||
|       LOG_INFO("send candidate [{}]", candidate.c_str()); | ||||
|       json message = {{"type", "candidate"}, {"sdp", candidate}}; | ||||
|       send_msg(answer_hdl_map_[transmission_id], message); | ||||
|       // send_msg(answer_hdl_map_[transmission_id], message); | ||||
|       break; | ||||
|     } | ||||
|     case "answer_candidate"_H: { | ||||
|       std::string transmission_id = j["transmission_id"]; | ||||
|       std::string candidate = j["sdp"]; | ||||
|       std::string transmission_id = j["transmission_id"].get<std::string>(); | ||||
|       std::string candidate = j["sdp"].get<std::string>(); | ||||
|       LOG_INFO("send candidate [{}]", candidate.c_str()); | ||||
|       json message = {{"type", "candidate"}, {"sdp", candidate}}; | ||||
|       send_msg(offer_hdl_map_[transmission_id], message); | ||||
|       // send_msg(offer_hdl_map_[transmission_id], message); | ||||
|       break; | ||||
|     } | ||||
|     default: | ||||
|   | ||||
| @@ -9,8 +9,7 @@ | ||||
| #include <websocketpp/config/asio_no_tls.hpp> | ||||
| #include <websocketpp/server.hpp> | ||||
|  | ||||
| #include "sdp_manager.h" | ||||
| #include "ws_handle_manager.h" | ||||
| #include "transmission_manager.h" | ||||
|  | ||||
| using nlohmann::json; | ||||
|  | ||||
| @@ -31,7 +30,7 @@ class SignalServer { | ||||
|  | ||||
|   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); | ||||
|  | ||||
| @@ -44,17 +43,9 @@ class SignalServer { | ||||
|       ws_connections_; | ||||
|   std::map<room_id, connection_id> rooms_; | ||||
|   unsigned int ws_connection_id_ = 0; | ||||
|   std::string transmission_id_ = "000000"; | ||||
|  | ||||
|   std::set<std::string> transmission_list_; | ||||
|  | ||||
|   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_; | ||||
|   TransmissionManager transmission_manager_; | ||||
| }; | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										80
									
								
								tests/signal_server/transmission_manager.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								tests/signal_server/transmission_manager.cpp
									
									
									
									
									
										Normal 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; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										42
									
								
								tests/signal_server/transmission_manager.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								tests/signal_server/transmission_manager.h
									
									
									
									
									
										Normal 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 | ||||
| @@ -1,5 +0,0 @@ | ||||
| #include "ws_handle_manager.h" | ||||
|  | ||||
| WsHandleManager::WsHandleManager() {} | ||||
|  | ||||
| WsHandleManager::~WsHandleManager() {} | ||||
| @@ -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 | ||||
							
								
								
									
										10
									
								
								xmake.lua
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								xmake.lua
									
									
									
									
									
								
							| @@ -32,6 +32,10 @@ target("log") | ||||
|     add_headerfiles("src/log/log.h") | ||||
|     add_includedirs("src/log", {public = true}) | ||||
|  | ||||
| target("common") | ||||
|     set_kind("headeronly") | ||||
|     add_includedirs("src/common", {public = true}) | ||||
|  | ||||
| target("inih") | ||||
|     set_kind("static") | ||||
|     add_files("src/inih/ini.c", "src/inih/INIReader.cpp") | ||||
| @@ -39,7 +43,7 @@ target("inih") | ||||
|  | ||||
| target("ice") | ||||
|     set_kind("static") | ||||
|     add_deps("log", "ws") | ||||
|     add_deps("log", "common", "ws") | ||||
|     add_packages("asio", "nlohmann_json", "libjuice") | ||||
|     add_files("src/ice/*.cpp") | ||||
|     add_includedirs("src/ws") | ||||
| @@ -55,7 +59,7 @@ target("ws") | ||||
| target("pc") | ||||
|     set_kind("static") | ||||
|     add_deps("log") | ||||
|     add_deps("ws", "ice", "inih") | ||||
|     add_deps("ws", "ice", "inih", "common") | ||||
|     add_files("src/pc/*.cpp") | ||||
|     add_packages("asio", "nlohmann_json") | ||||
|     add_includedirs("src/ws", "src/ice") | ||||
| @@ -73,7 +77,7 @@ target("projectx") | ||||
|  | ||||
| target("signal_server") | ||||
|     set_kind("binary") | ||||
|     add_deps("log") | ||||
|     add_deps("log", "common") | ||||
|     add_files("tests/signal_server/*.cpp") | ||||
|     add_packages("asio", "nlohmann_json", "spdlog") | ||||
|     add_includedirs("thirdparty/websocketpp/include") | ||||
|   | ||||
		Reference in New Issue
	
	Block a user