offerer.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /**
  2. * Copyright (c) 2019 Paul-Louis Ageneau
  3. * Copyright (c) 2019 Murat Dogan
  4. *
  5. * This Source Code Form is subject to the terms of the Mozilla Public
  6. * License, v. 2.0. If a copy of the MPL was not distributed with this
  7. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
  8. */
  9. #include "rtc/rtc.hpp"
  10. #include <chrono>
  11. #include <iostream>
  12. #include <memory>
  13. #include <thread>
  14. using namespace std::chrono_literals;
  15. using std::shared_ptr;
  16. using std::weak_ptr;
  17. template <class T> weak_ptr<T> make_weak_ptr(shared_ptr<T> ptr) { return ptr; }
  18. int main(int argc, char **argv) {
  19. rtc::InitLogger(rtc::LogLevel::Warning);
  20. rtc::Configuration config;
  21. // config.iceServers.emplace_back("stun.l.google.com:19302");
  22. auto pc = std::make_shared<rtc::PeerConnection>(config);
  23. pc->onLocalDescription([](rtc::Description description) {
  24. std::cout << "Local Description (Paste this to the other peer):" << std::endl;
  25. std::cout << std::string(description) << std::endl;
  26. });
  27. pc->onLocalCandidate([](rtc::Candidate candidate) {
  28. std::cout << "Local Candidate (Paste this to the other peer after the local description):"
  29. << std::endl;
  30. std::cout << std::string(candidate) << std::endl << std::endl;
  31. });
  32. pc->onStateChange([](rtc::PeerConnection::State state) {
  33. std::cout << "[State: " << state << "]" << std::endl;
  34. });
  35. pc->onGatheringStateChange([](rtc::PeerConnection::GatheringState state) {
  36. std::cout << "[Gathering State: " << state << "]" << std::endl;
  37. });
  38. auto dc = pc->createDataChannel("test"); // this is the offerer, so create a data channel
  39. dc->onOpen([&]() { std::cout << "[DataChannel open: " << dc->label() << "]" << std::endl; });
  40. dc->onClosed(
  41. [&]() { std::cout << "[DataChannel closed: " << dc->label() << "]" << std::endl; });
  42. dc->onMessage([](auto data) {
  43. if (std::holds_alternative<std::string>(data)) {
  44. std::cout << "[Received: " << std::get<std::string>(data) << "]" << std::endl;
  45. }
  46. });
  47. std::this_thread::sleep_for(1s);
  48. bool exit = false;
  49. while (!exit) {
  50. std::cout
  51. << std::endl
  52. << "**********************************************************************************"
  53. "*****"
  54. << std::endl
  55. << "* 0: Exit /"
  56. << " 1: Enter remote description /"
  57. << " 2: Enter remote candidate /"
  58. << " 3: Send message /"
  59. << " 4: Print Connection Info *" << std::endl
  60. << "[Command]: ";
  61. int command = -1;
  62. std::cin >> command;
  63. std::cin.ignore();
  64. switch (command) {
  65. case 0: {
  66. exit = true;
  67. break;
  68. }
  69. case 1: {
  70. // Parse Description
  71. std::cout << "[Description]: ";
  72. std::string sdp, line;
  73. while (getline(std::cin, line) && !line.empty()) {
  74. sdp += line;
  75. sdp += "\r\n";
  76. }
  77. pc->setRemoteDescription(sdp);
  78. break;
  79. }
  80. case 2: {
  81. // Parse Candidate
  82. std::cout << "[Candidate]: ";
  83. std::string candidate;
  84. getline(std::cin, candidate);
  85. pc->addRemoteCandidate(candidate);
  86. break;
  87. }
  88. case 3: {
  89. // Send Message
  90. if (!dc->isOpen()) {
  91. std::cout << "** Channel is not Open ** ";
  92. break;
  93. }
  94. std::cout << "[Message]: ";
  95. std::string message;
  96. getline(std::cin, message);
  97. dc->send(message);
  98. break;
  99. }
  100. case 4: {
  101. // Connection Info
  102. if (!dc || !dc->isOpen()) {
  103. std::cout << "** Channel is not Open ** ";
  104. break;
  105. }
  106. rtc::Candidate local, remote;
  107. std::optional<std::chrono::milliseconds> rtt = pc->rtt();
  108. if (pc->getSelectedCandidatePair(&local, &remote)) {
  109. std::cout << "Local: " << local << std::endl;
  110. std::cout << "Remote: " << remote << std::endl;
  111. std::cout << "Bytes Sent:" << pc->bytesSent()
  112. << " / Bytes Received:" << pc->bytesReceived() << " / Round-Trip Time:";
  113. if (rtt.has_value())
  114. std::cout << rtt.value().count();
  115. else
  116. std::cout << "null";
  117. std::cout << " ms";
  118. } else {
  119. std::cout << "Could not get Candidate Pair Info" << std::endl;
  120. }
  121. break;
  122. }
  123. default: {
  124. std::cout << "** Invalid Command **" << std::endl;
  125. break;
  126. }
  127. }
  128. }
  129. if (dc)
  130. dc->close();
  131. if (pc)
  132. pc->close();
  133. }