mirror of
https://github.com/mii443/libdatachannel.git
synced 2025-08-22 23:25:33 +00:00
Uncluttered client example to keep it simple
This commit is contained in:
@ -23,17 +23,19 @@
|
||||
|
||||
#include "rtc/rtc.hpp"
|
||||
|
||||
#include "parse_cl.h"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <future>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <random>
|
||||
#include <thread>
|
||||
#include <future>
|
||||
#include <stdexcept>
|
||||
#include <thread>
|
||||
#include <unordered_map>
|
||||
#include "parse_cl.h"
|
||||
|
||||
|
||||
using namespace rtc;
|
||||
using namespace std;
|
||||
@ -47,25 +49,23 @@ unordered_map<string, shared_ptr<PeerConnection>> peerConnectionMap;
|
||||
unordered_map<string, shared_ptr<DataChannel>> dataChannelMap;
|
||||
|
||||
string localId;
|
||||
bool echoDataChannelMessages = false;
|
||||
|
||||
shared_ptr<PeerConnection> createPeerConnection(const Configuration &config,
|
||||
weak_ptr<WebSocket> wws, string id);
|
||||
void printReceived(bool echoed, string id, string type, size_t length);
|
||||
string randomId(size_t length);
|
||||
|
||||
|
||||
int main(int argc, char **argv) try {
|
||||
auto params = std::make_unique<Cmdline>(argc, argv);
|
||||
|
||||
rtc::InitLogger(LogLevel::Debug);
|
||||
rtc::InitLogger(LogLevel::Info);
|
||||
|
||||
Configuration config;
|
||||
string stunServer = "";
|
||||
if (params->noStun()) {
|
||||
cout << "No STUN server is configured. Only local hosts and public IP addresses supported." << endl;
|
||||
cout << "No STUN server is configured. Only local hosts and public IP addresses supported."
|
||||
<< endl;
|
||||
} else {
|
||||
if (params->stunServer().substr(0,5).compare("stun:") != 0) {
|
||||
if (params->stunServer().substr(0, 5).compare("stun:") != 0) {
|
||||
stunServer = "stun:";
|
||||
}
|
||||
stunServer += params->stunServer() + ":" + to_string(params->stunPort());
|
||||
@ -76,27 +76,23 @@ int main(int argc, char **argv) try {
|
||||
localId = randomId(4);
|
||||
cout << "The local ID is: " << localId << endl;
|
||||
|
||||
echoDataChannelMessages = params->echoDataChannelMessages();
|
||||
cout << "Received data channel messages will be "
|
||||
<< (echoDataChannelMessages ? "echoed back to sender" : "printed to stdout") << endl;
|
||||
|
||||
auto ws = make_shared<WebSocket>();
|
||||
|
||||
std::promise<void> wsPromise;
|
||||
auto wsFuture = wsPromise.get_future();
|
||||
|
||||
ws->onOpen([&wsPromise]() {
|
||||
|
||||
ws->onOpen([&wsPromise]() {
|
||||
cout << "WebSocket connected, signaling ready" << endl;
|
||||
wsPromise.set_value();
|
||||
});
|
||||
|
||||
ws->onError([&wsPromise](string s) {
|
||||
ws->onError([&wsPromise](string s) {
|
||||
cout << "WebSocket error" << endl;
|
||||
wsPromise.set_exception(std::make_exception_ptr(std::runtime_error(s)));
|
||||
});
|
||||
|
||||
|
||||
ws->onClosed([]() { cout << "WebSocket closed" << endl; });
|
||||
|
||||
|
||||
ws->onMessage([&](variant<binary, string> data) {
|
||||
if (!holds_alternative<string>(data))
|
||||
return;
|
||||
@ -134,14 +130,14 @@ int main(int argc, char **argv) try {
|
||||
});
|
||||
|
||||
string wsPrefix = "";
|
||||
if (params->webSocketServer().substr(0,5).compare("ws://") != 0) {
|
||||
if (params->webSocketServer().substr(0, 5).compare("ws://") != 0) {
|
||||
wsPrefix = "ws://";
|
||||
}
|
||||
const string url = wsPrefix + params->webSocketServer() + ":" +
|
||||
to_string(params->webSocketPort()) + "/" + localId;
|
||||
to_string(params->webSocketPort()) + "/" + localId;
|
||||
cout << "Url is " << url << endl;
|
||||
ws->open(url);
|
||||
|
||||
|
||||
cout << "Waiting for signaling to be connected..." << endl;
|
||||
wsFuture.get();
|
||||
|
||||
@ -172,19 +168,11 @@ int main(int argc, char **argv) try {
|
||||
dc->onClosed([id]() { cout << "DataChannel from " << id << " closed" << endl; });
|
||||
|
||||
dc->onMessage([id, wdc = make_weak_ptr(dc)](const variant<binary, string> &message) {
|
||||
static bool firstMessage = true;
|
||||
if (holds_alternative<string>(message) && (!echoDataChannelMessages || firstMessage)) {
|
||||
if (holds_alternative<string>(message))
|
||||
cout << "Message from " << id << " received: " << get<string>(message) << endl;
|
||||
firstMessage = false;
|
||||
} else if (echoDataChannelMessages) {
|
||||
bool echoed = false;
|
||||
if (auto dc = wdc.lock()) {
|
||||
dc->send(message);
|
||||
echoed = true;
|
||||
}
|
||||
printReceived(echoed, id, (holds_alternative<string>(message) ? "text" : "binary"),
|
||||
get<string>(message).length());
|
||||
}
|
||||
else
|
||||
cout << "Binary message from " << id
|
||||
<< " received, size=" << get<binary>(message).size() << endl;
|
||||
});
|
||||
|
||||
dataChannelMap.emplace(id, dc);
|
||||
@ -238,19 +226,11 @@ shared_ptr<PeerConnection> createPeerConnection(const Configuration &config,
|
||||
dc->onClosed([id]() { cout << "DataChannel from " << id << " closed" << endl; });
|
||||
|
||||
dc->onMessage([id, wdc = make_weak_ptr(dc)](const variant<binary, string> &message) {
|
||||
static bool firstMessage = true;
|
||||
if (holds_alternative<string>(message) && (!echoDataChannelMessages || firstMessage)) {
|
||||
if (holds_alternative<string>(message))
|
||||
cout << "Message from " << id << " received: " << get<string>(message) << endl;
|
||||
firstMessage = false;
|
||||
} else if (echoDataChannelMessages) {
|
||||
bool echoed = false;
|
||||
if (auto dc = wdc.lock()) {
|
||||
dc->send(message);
|
||||
echoed = true;
|
||||
}
|
||||
printReceived(echoed, id, (holds_alternative<string>(message) ? "text" : "binary"),
|
||||
get<string>(message).length());
|
||||
}
|
||||
else
|
||||
cout << "Binary message from " << id
|
||||
<< " received, size=" << get<binary>(message).size() << endl;
|
||||
});
|
||||
|
||||
dc->send("Hello from " + localId);
|
||||
@ -262,20 +242,6 @@ shared_ptr<PeerConnection> createPeerConnection(const Configuration &config,
|
||||
return pc;
|
||||
};
|
||||
|
||||
// Helper function to print received pings
|
||||
void printReceived(bool echoed, string id, string type, size_t length) {
|
||||
static long count = 0;
|
||||
static long freq = 100;
|
||||
if (!(++count%freq)) {
|
||||
cout << "Received " << count << " pings in total from " << id << ", most recent of type "
|
||||
<< type << " and " << (echoed ? "" : "un") << "successfully echoed most recent ping of size "
|
||||
<< length << " back to " << id << endl;
|
||||
if (count >= (freq * 10) && freq < 1000000) {
|
||||
freq *= 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to generate a random ID
|
||||
string randomId(size_t length) {
|
||||
static const string characters(
|
||||
|
@ -43,47 +43,39 @@ Cmdline::Cmdline (int argc, char *argv[]) // ISO C++17 not allowed: throw (std::
|
||||
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{"echo", no_argument, NULL, 'e'},
|
||||
{"noStun", no_argument, NULL, 'n'},
|
||||
{"stunServer", required_argument, NULL, 's'},
|
||||
{"stunPort", required_argument, NULL, 't'},
|
||||
{"webSocketServer", required_argument, NULL, 'w'},
|
||||
{"webSocketPort", required_argument, NULL, 'x'},
|
||||
{"help", no_argument, NULL, 'h'},
|
||||
{"version", no_argument, NULL, 'v'},
|
||||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
|
||||
_program_name += argv[0];
|
||||
|
||||
/* default values */
|
||||
_e = false;
|
||||
_n = false;
|
||||
_s = "stun.l.google.com";
|
||||
_t = 19302;
|
||||
_w = "localhost";
|
||||
_x = 8000;
|
||||
_h = false;
|
||||
_v = false;
|
||||
|
||||
optind = 0;
|
||||
while ((c = getopt_long (argc, argv, "s:t:w:x:enhv", long_options, &optind)) != - 1)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'e':
|
||||
_e = true;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
case 'n':
|
||||
_n = true;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
case 's':
|
||||
_s = optarg;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
case 't':
|
||||
_t = atoi (optarg);
|
||||
if (_t < 0)
|
||||
{
|
||||
@ -99,11 +91,11 @@ Cmdline::Cmdline (int argc, char *argv[]) // ISO C++17 not allowed: throw (std::
|
||||
}
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
case 'w':
|
||||
_w = optarg;
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
case 'x':
|
||||
_x = atoi (optarg);
|
||||
if (_x < 0)
|
||||
{
|
||||
@ -119,16 +111,11 @@ Cmdline::Cmdline (int argc, char *argv[]) // ISO C++17 not allowed: throw (std::
|
||||
}
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
case 'h':
|
||||
_h = true;
|
||||
this->usage (EXIT_SUCCESS);
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
_v = true;
|
||||
this->version (EXIT_SUCCESS);
|
||||
break;
|
||||
|
||||
default:
|
||||
this->usage (EXIT_FAILURE);
|
||||
|
||||
@ -155,8 +142,6 @@ void Cmdline::usage (int status)
|
||||
std::cout << "\
|
||||
usage: " << _program_name << " [ -enstwxhv ] \n\
|
||||
libdatachannel client implementing WebRTC Data Channels with WebSocket signaling\n\
|
||||
[ -e ] [ --echo ] (type=FLAG)\n\
|
||||
Echo data channel messages back to sender rather than putting to stdout.\n\
|
||||
[ -n ] [ --noStun ] (type=FLAG)\n\
|
||||
Do NOT use a stun server (overrides -s and -t).\n\
|
||||
[ -s ] [ --stunServer ] (type=STRING, default=stun.l.google.com)\n\
|
||||
@ -168,15 +153,8 @@ libdatachannel client implementing WebRTC Data Channels with WebSocket signaling
|
||||
[ -x ] [ --webSocketPort ] (type=INTEGER, range=0...65535, default=8000)\n\
|
||||
Web socket server port.\n\
|
||||
[ -h ] [ --help ] (type=FLAG)\n\
|
||||
Display this help and exit.\n\
|
||||
[ -v ] [ --version ] (type=FLAG)\n\
|
||||
Output version information and exit.\n";
|
||||
Display this help and exit.\n";
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
|
||||
void Cmdline::version (int status)
|
||||
{
|
||||
std::cout << _program_name << " v0.5\n";
|
||||
exit (status);
|
||||
}
|
||||
|
@ -34,14 +34,12 @@ class Cmdline
|
||||
{
|
||||
private:
|
||||
/* parameters */
|
||||
bool _e;
|
||||
bool _n;
|
||||
std::string _s;
|
||||
int _t;
|
||||
std::string _w;
|
||||
int _x;
|
||||
bool _h;
|
||||
bool _v;
|
||||
|
||||
/* other stuff to keep track of */
|
||||
std::string _program_name;
|
||||
@ -55,20 +53,15 @@ public:
|
||||
/* usage function */
|
||||
void usage (int status);
|
||||
|
||||
/* version function */
|
||||
void version (int status);
|
||||
|
||||
/* return next (non-option) parameter */
|
||||
int next_param () { return _optind; }
|
||||
|
||||
bool echoDataChannelMessages () const { return _e; }
|
||||
bool noStun () const { return _n; }
|
||||
std::string stunServer () const { return _s; }
|
||||
int stunPort () const { return _t; }
|
||||
std::string webSocketServer () const { return _w; }
|
||||
int webSocketPort () const { return _x; }
|
||||
bool h () const { return _h; }
|
||||
bool v () const { return _v; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user