Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
@testrtc/watchrtc-sdk
Advanced tools
Monitor your WebRTC application by collecting WebRTC statistics from end users
watchRTC enables application developers to collect, track and analyze telemetry and metrics of real users on any WebRTC application. This is done by including our watchRTC SDK which connects to the testRTC backend and collects the relevant data. Please check out our watchRTC knowledge base to learn more about the features and capabilities of this WebRTC monitoring service.
npm install @testrtc/watchrtc-sdk
yarn add @testrtc/watchrtc-sdk
<script src="https://unpkg.com/@testrtc/watchrtc-sdk/lib/index.js"></script>
Before any of your WebRTC javascript code, you need to include and initialize our SDK.
The watchRTC.init() needs to take place prior to including or loading any 3rd party SDKs that interact with WebRTC - failing to do so may hinder our ability to collect data. Use the following initialization sequence:
const watchRTC = require("@testrtc/watchrtc-sdk");
watchRTC.init();
import watchRTC from "@testrtc/watchrtc-sdk";
watchRTC.init();
with CDN
<!doctype html>
<html lang="en">
<head>
<title>watchRT SDK</title>
</head>
<body>
<script src="https://unpkg.com/@testrtc/watchrtc-sdk/lib/index.js"></script>
<script>
watchRTC.init();
</script>
</body>
</html>
Before you start, be sure to also read our Getting started with watchRTC guide. Configuring the SDK to connect to the watchRTC backend requires passing the following parameters to the SDK:
watchRTC.init()
watchRTC.setConfig()
RTCPeerConnection()
Passing configuration parameters in the init() is the direct/easy way to provide this information.
This is useful if you are planning to use a known/specific roomId for this session.
The disadvantage of this approach is that it is rigid, and doesn't allow much flexibility.
You can call the init()
function multiple times, but it will be initialized only on the first call.
watchRTC.init({
rtcApiKey: "watchRTC API key",
rtcRoomId: "identifier for the session",
rtcPeerId: "identifier for the current peer",
keys: { key1: "value1", key2: "value2" },
console: { level: "error", override: true },
proxyUrl: "wss://{your-proxy}",
collectionInterval: 8,
});
You can call init()
multiple times, but it will be initialized only at the first time. Following calls will be ignored.
You can use watchRTC.setConfig()
function to set watchRTC configuration after calling watchRTC.init()
and before the creation of RTCPeerConnection objects.
This approach is useful if you don't have the information needed in your watchRTC.init()
call or when you don't have direct/easy access to the RTCPeerConnection objects (for example, when using a third party CPaaS SDK).
If needed, you can pass the rtcApiKey in the watchRTC.init()
call while passing the rtcRomId, rtcPeerId and keys in the watchRTC.setConfig()
call.
You can call this function multiple times, usually whenever a new session/room needs to be created or entered.
watchRTC.setConfig({
rtcApiKey: "watchRTC API key",
rtcRoomId: "identifier for the session",
rtcPeerId: "identifier for the current peer",
keys: { key1: "value1", key2: "value2" },
console: { level: "error", override: true },
});
If you have direct access to the RTCPeerConnection object creation, then you can add the necessary configuration parameters there. This gives you the highest level of control over what is done.
var pc = new RTCPeerConnection({
...,
watchrtc:{
rtcApiKey: "watchRTC API key",
rtcRoomId: "identifier for the session",
rtcPeerId: "identifier for the current peer",
keys: { key1: "value1", key2: "value2" },
console: { level: "error", override: true }
}
});
You can also add keys to a room after joining the room. This can be done by calling watchRTC.addKeys()
function.
Returns a Promise
which resolves with an empty object in success case, or with an error
property if something went wrong.
watchRTC.addKeys({ key1: "value1", key2: "value2" });
When needed, you can temporarily disable data collection. This is important for example if you want to conduct a pre-call test but you aren't interested in collecting that data.
For that, you can use watchRTC.enableDataCollection()
and watchRTC.disableDataCollection()
to control what data you want to send.
You can collect the user's feedback as well. This can be done by calling watchRTC.setUserRating()
.
Returns a Promise
which resolves with an empty object in success case, or with an error
property if something went wrong.
watchRTC.setUserRating(5, "the best video quality I ever experienced!");
You can add your own events to the graphs and event logs. This enables you to monitor specific activity that you are interested in that is outside the generic scope of how WebRTC operates but part of your application logic. This is done by calling watchRTC.addEvent()
.
Returns a Promise
which resolves with an empty object in success case, or with an error
property if something went wrong.
Read more about adding custom events in watchRTC.
watchRTC.addEvent({ name: "my event", type: "global", parameters: { param1: "value1" } });
Starting version 1.38, events can be associated to a RTCPeerConnection
. Here is an example:
const audioPc = new RTCPeerConnection();
// At any time during the call
watchRTC.addEvent({
name: "muted",
type: "local",
parameters: { value: true },
pc: audioPc,
});
By default, watchRTC will assign the SSRC information as the name for incoming channels. You can change these to human-readable format indicating the source of the channels by mapping their streams. This is done by calling watchRTC.mapTrack(trackIdentifier)
. Read more about mapping streams in watchRTC.
watchRTC.mapTrack("c085d50a-bb28-4d9f-97b1-86bfc646e5b0", "User A");
Note: The trackIdentifier
corresponds to the remote RTCMediaStreamTrack's Id attribute.
In call center scenarios, there's a feature called persistent connection or nailup call. With it, a WebRTC peer connection is created and maintained, while actual real calls take place on top of that single connection, keeping it open in-between these calls. This is used to reduce call setup times and to reduce the amount of needed signaling messages. You can mark the begining and end of such application specific calls on a persistent connection using watchRTC.persistentStart(rtcRoomId, rtcPeerId)
and watchRTC.persistentEnd()
. Read more about persistent connections and watchRTC.
Note: Make sure to pass new rtcRoomId for next call in order to separate sessions.
By default, watchRTC SDK will automatically establish a connection with the watchRTC server and close it after an idle period. At times, it might make sense for your application to manually open and close that connection explicitly. This is done by calling watchRTC.connect()
and watchRTC.disconnect()
. Read more about manually connecting/disconnecting to watchRTC servers.
watchRTC.connect();
watchRTC.disconnect();
Be careful, this API is in beta. API and content could change in future releases. Once a call is established, WatchRTC exposes WebRTC statistics collected from the existing RTCPeerConnections. Accessing to these statistics can be done by adding a listener from the application.
const statsListener = (stats) => {
// Called each time new statistics are available
};
watchRTC.addStatsListener(statsListener);
Each time new statistic are available, the listener will be called with a JSON object containing the statistics. The JSON object contains 2 main properties:
For each connection in connections, the following properties are available:
direct
or relay
,udp
, tcp
or tls
,For each stream in streams, the following properties are available:
audio
or video
,inbound
or outbound
,mapTrack
and associated with this stream. null
by default,Note: To stop receiving the statistics, pass null
to the addStatsListener
function. The existing listener will be unsubscribed and removed.
Once the watchRTC SDK is initialized, it will report its state changes. Listening to the state can be done by adding a listener from your application.
const stateListener = (state) => {
// Called each time SDK state is changed
};
watchRTC.addStateListener(stateListener);
Each time the state changes, the listener will be called with a JSON object containing new state. The JSON object contains 1 property:
connected
or disconnected
,disconnected
). The reason of the state change. Can be one of clientRejectedNoRetry
, disconnectedPrematurely
, cantConnectToServer
, serverRejectedNoRetry
or applicationDisconnected
.Here is some additional information about the reasons:
clientRejectedNoRetry
: The SDK has been disconnected because the configuration was incorrect. This can happen when the fields rtcApiKey
, rtcRoomId
or rtcPeerId
are missing. The SDK will not try to reconnect automatically.disconnectedPrematurely
: The SDK has been disconnected because the connection was lost. It will automatically try to reconnect using an exponential backoff mechanism.cantConnectToServer
: The SDK is disconnected and has failed to connect. It will try to reconnect automatically using an exponential backoff mechanism.serverRejectedNoRetry
: The SDK has been disconnected because the server has rejected the connection. This can happen when the authentication using the rtcApiKey
fails. The SDK will not try to reconnect.applicationDisconnected
: The SDK has been disconnected because the application has called the disconnect
method or because the SDK automatically disconnects when all peer-connections have been closed. The SDK will not try to reconnect automatically.Note: To stop listening, pass null
to the addStateListener()
function. The existing listener will be unsubscribed and removed.
If you have licensed qualityRTC, then you can also conduct ad-hoc network tests to your agents and users as an integral part of your application, to quickly understand and troubleshoot WebRTC connectivity and quality issues.
Learn more about qualityRTC SDK.
const progressCallback = (progress: number) => {
console.log(`runNetworkTest progressCallback ${progress}%`, {});
}
const runNetworkTest = async (testName: string) => {
const answer = await watchRTC.qualityrtc.run({
options: {
// run: "Location",
// any other parameter from https://support.testrtc.com/hc/en-us/articles/8428284359823-URL-parameters-in-qualityRTC
},
progressCallback
});
// any time can call stop to stop the test
// watchRTC.qualityrtc.stop();
// answer is in the format described in https://support.testrtc.com/hc/en-us/articles/8428324242319-Webhook-support-in-qualityRTC
console.log(`runNetworkTest answer`, answer);
}
Additional samples on how to integrate the watchRTC SDK can be found on our official GitHub repository: https://github.com/testRTC/sample-Twilio-video-app-React-TypeScript-watchRTC
userAgentData
message to correctly detect the name and version of the OS used when on iPad.userAgentData
containing the Client Hints information if available.connect()
method has been called and when the last active peer-connection has been closed manually.newConnection
on WS handshake to detect new connection from reconnecting.mapPC
function to map peer connection to human-readable names.cantConnectToServerMaxAttemptsNoRetry
nostats
message when statistics reports are not sent to the serverdisconnected
added server side compatibility.
fixed statsListener to allow passing null
to remove the callback
logLevel
configuration property to give more control over logs on SDK initializationdebug
configuration property in favor of logLevel
track.mute
and track.unmute
events to minimize messages in logs in the case of large rooms or for peers with large number of channels.persistentStart()
is done. This avoids the initial spike in graphs.pc
property in addEvent
to associate the event to an existing RTCPeerConnection
codec
in statsListenerRTCPeerConnection
getStats
logs in debug mode to reduce resources usagelogGetStats
configuration property to enable getStats
logs if neededpersistentStart
and persistentEnd
methodswatchRTC.persistentStart(rtcRoomId, rtcPeerId)
and watchRTC.persistentEnd()
to start/stop nail up call. Make sure to pass new rtcRoomId for next call in order to separate sessions.watchRTC.mapStream() method is deprecated and should be replaced by watchRTC.mapTrack()
watchRTC.mapTrack()
was addedmappedName
added to the statsListener
which contains the name associated to the stream.watchRTC.addStateListener()
was addedsetConfig
addEvent
now works more accurately for events captured before the websocket connection was established to the watchRTC serverawait
on the following SDK methods: addKeys()
, setUserRating()
, addEvent()
. These methods now return a Promise
which resolves with an empty object on success case, or with an error
property if something went wrongwatchRTC.addEvent()
now also supports parameterswatchRTC.mapStream()
was added. Read more about mapping streams in watchRTCwatchRTC.addEvent()
was added. Read more about events in watchRTCwatchRTC.addTags()
was deprecated. We no longer support tags. These have been replaced with a key/value systemwatchRTC.addKeys()
was added. Read more about keys in watchRTCwatchRTC.addTags()
was addedwatchRTC.setUserRating()
was addedFAQs
Monitor your WebRTC application by collecting WebRTC statistics from end users
We found that @testrtc/watchrtc-sdk demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 4 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.