Skip to content

Commit

Permalink
Add WebRtcConnection stats to json (#1474)
Browse files Browse the repository at this point in the history
  • Loading branch information
jcague authored Oct 8, 2019
1 parent 4024010 commit 2d69aba
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 7 deletions.
10 changes: 10 additions & 0 deletions erizo/src/erizo/WebRtcConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,9 @@ boost::future<void> WebRtcConnection::setRemoteSdpInfo(
return;
}
connection->remote_sdp_ = sdp;
if (connection->pipeline_initialized_ && connection->pipeline_) {
connection->pipeline_->notifyUpdate();
}
boost::future<void> future = connection->processRemoteSdp().then(
[task_promise] (boost::future<void>) {
task_promise->set_value();
Expand Down Expand Up @@ -854,4 +857,11 @@ void WebRtcConnection::setTransport(std::shared_ptr<Transport> transport) { //
bundle_ = true;
}

void WebRtcConnection::getJSONStats(std::function<void(std::string)> callback) {
asyncTask([callback] (std::shared_ptr<WebRtcConnection> connection) {
std::string requested_stats = connection->stats_->getStats();
callback(requested_stats);
});
}

} // namespace erizo
1 change: 1 addition & 0 deletions erizo/src/erizo/WebRtcConnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ class WebRtcConnection: public TransportListener, public LogContext, public Hand
void write(std::shared_ptr<DataPacket> packet);
void notifyUpdateToHandlers() override;
ConnectionQualityLevel getConnectionQualityLevel();
void getJSONStats(std::function<void(std::string)> callback);

private:
bool createOfferSync(bool video_enabled, bool audio_enabled, bool bundle);
Expand Down
42 changes: 42 additions & 0 deletions erizoAPI/WebRtcConnection.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,33 @@ Nan::Persistent<Function> WebRtcConnection::constructor;

DEFINE_LOGGER(WebRtcConnection, "ErizoAPI.WebRtcConnection");

ConnectionStatCallWorker::ConnectionStatCallWorker(
Nan::Callback *callback, std::weak_ptr<erizo::WebRtcConnection> weak_connection)
: Nan::AsyncWorker{callback}, weak_connection_{weak_connection}, stat_{""} {
}

void ConnectionStatCallWorker::Execute() {
std::promise<std::string> stat_promise;
std::future<std::string> stat_future = stat_promise.get_future();
if (auto connection = weak_connection_.lock()) {
connection->getJSONStats([&stat_promise] (std::string stats) {
stat_promise.set_value(stats);
});
} else {
stat_promise.set_value(std::string("{}"));
}
stat_future.wait();
stat_ = stat_future.get();
}

void ConnectionStatCallWorker::HandleOKCallback() {
Local<Value> argv[] = {
Nan::New<v8::String>(stat_).ToLocalChecked()
};
Nan::AsyncResource resource("erizo::addon.statCall");
callback->Call(1, argv, &resource);
}

void destroyWebRtcConnectionAsyncHandle(uv_handle_t *handle) {
delete handle;
}
Expand Down Expand Up @@ -98,6 +125,7 @@ NAN_MODULE_INIT(WebRtcConnection::Init) {
Nan::SetPrototypeMethod(tpl, "addMediaStream", addMediaStream);
Nan::SetPrototypeMethod(tpl, "removeMediaStream", removeMediaStream);
Nan::SetPrototypeMethod(tpl, "copySdpToLocalDescription", copySdpToLocalDescription);
Nan::SetPrototypeMethod(tpl, "getStats", getStats);

constructor.Reset(tpl->GetFunction());
Nan::Set(target, Nan::New("WebRtcConnection").ToLocalChecked(), Nan::GetFunction(tpl).ToLocalChecked());
Expand Down Expand Up @@ -484,6 +512,20 @@ NAN_METHOD(WebRtcConnection::removeMediaStream) {
info.GetReturnValue().Set(resolver->GetPromise());
}

NAN_METHOD(WebRtcConnection::getStats) {
WebRtcConnection* obj = Nan::ObjectWrap::Unwrap<WebRtcConnection>(info.Holder());
std::shared_ptr<erizo::WebRtcConnection> me = obj->me;
Nan::Callback *callback = new Nan::Callback(info[0].As<Function>());
if (!me || info.Length() != 1 || obj->closed_) {
Local<Value> argv[] = {
Nan::New<v8::String>("{}").ToLocalChecked()
};
Nan::Call(*callback, 1, argv);
return;
}
AsyncQueueWorker(new ConnectionStatCallWorker(callback, obj->me));
}

// Async methods

void WebRtcConnection::notifyEvent(erizo::WebRTCEvent event, const std::string& message) {
Expand Down
15 changes: 15 additions & 0 deletions erizoAPI/WebRtcConnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,19 @@
typedef boost::variant<std::string, std::shared_ptr<erizo::SdpInfo>> ResultVariant;
typedef std::pair<Nan::Persistent<v8::Promise::Resolver> *, ResultVariant> ResultPair;

class ConnectionStatCallWorker : public Nan::AsyncWorker {
public:
ConnectionStatCallWorker(Nan::Callback *callback, std::weak_ptr<erizo::WebRtcConnection> weak_connection);

void Execute();

void HandleOKCallback();

private:
std::weak_ptr<erizo::WebRtcConnection> weak_connection_;
std::string stat_;
};

/*
* Wrapper class of erizo::WebRtcConnection
*
Expand Down Expand Up @@ -120,6 +133,8 @@ class WebRtcConnection : public erizo::WebRtcConnectionEventListener,

static NAN_METHOD(copySdpToLocalDescription);

static NAN_METHOD(getStats);

static Nan::Persistent<v8::Function> constructor;

static NAUV_WORK_CB(eventsCallback);
Expand Down
7 changes: 7 additions & 0 deletions erizo_controller/erizoJS/models/Connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,13 @@ class Connection extends events.EventEmitter {
return this.mediaStreams.size;
}

getStats(callback) {
if (!this.wrtc) {
return true;
}
return this.wrtc.getStats(callback);
}

close() {
log.info(`message: Closing connection ${this.id}`);
log.info(`message: WebRtcConnection status update, id: ${this.id}, status: ${CONN_FINISHED}, ` +
Expand Down
23 changes: 16 additions & 7 deletions erizo_controller/erizoJS/models/Node.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,29 @@ class Node extends EventEmitter {
}

getStats(label, stats) {
const promise = new Promise((resolve) => {
if (!this.mediaStream || !this.connection) {
resolve();
return;
}
if (!this.mediaStream || !this.connection) {
return Promise.resolve();
}
// eslint-disable-next-line no-param-reassign
stats[label] = {};
const streamStatsPromise = new Promise((resolve) => {
this.mediaStream.getStats((statsString) => {
const unfilteredStats = JSON.parse(statsString);
unfilteredStats.metadata = this.connection.metadata;
// eslint-disable-next-line no-param-reassign
stats[label] = unfilteredStats;
Object.assign(stats[label], unfilteredStats);
resolve();
});
});
const connectionStatsPromise = new Promise((resolve) => {
this.connection.getStats((statsString) => {
const unfilteredStats = JSON.parse(statsString);
// eslint-disable-next-line no-param-reassign
stats[label].connection = unfilteredStats;
resolve();
});
});
return promise;
return Promise.all([streamStatsPromise, connectionStatsPromise]);
}

_onMonitorMinVideoBWCallback(type, message) {
Expand Down

0 comments on commit 2d69aba

Please sign in to comment.