In-Session Communication
Beyond audio and video, EnableX sessions support a rich set of data communication features: text chat, file sharing, custom signaling, annotation on remote streams, screen sharing, and canvas streaming. None of these features require a published media stream to work — a chat-only participant can send and receive messages without a camera or microphone.
sendMessage() sends a text message to one participant, a group, or everyone in the room.
The sender does not need to have a published stream for messaging to work.
- Public messaging — set
isBroadcast: trueand pass an emptyrecipientIDsarray - Private / group messaging — set
isBroadcast: falseand list the target client IDs inrecipientIDs
- Method:
window.EnxRtc.sendMessage(message, isBroadcast, recipientIDs)
| Event | Fired To | Description |
|---|---|---|
onAcknowledgedSendData | Sender | Confirms the message was delivered successfully |
onMessageReceived | Recipients | Delivers the incoming message to each recipient |
// Public broadcast to everyone
window.EnxRtc.sendMessage("Hello everyone!", true, []);
// Private message to a specific participant
window.EnxRtc.sendMessage("Hi there", false, ["client_id_123"]);
// Sender acknowledgement
window.EnxRtc.addEventListner("onAcknowledgedSendData", function(data) {
console.log("Message delivered:", JSON.stringify(data.data));
});
// Incoming message at receiver's end
window.EnxRtc.addEventListner("onMessageReceived", function(data) {
var msg = data.data;
console.log("New message from:", msg.senderId, "—", msg.message);
appendMessageToChat(msg);
});
Session participants can share files with each other using a two-step process: the sender uploads the file to the EnableX server, and recipients are notified when the file is ready to download.
Upload a File for Sharing
sendFiles() initiates a file transfer to the EnableX server. You can broadcast the file
to all participants or target specific recipients by their client IDs.
- Method:
window.EnxRtc.sendFiles(isBroadcast, recipientIDs)
| Event | Fired To | Description |
|---|---|---|
onInitFileUpload | Sender | Upload process has started |
onFileUploaded | Sender | File has been uploaded successfully |
onFileUploadFailed | Sender | Upload failed (see error codes below) |
onFileUploadStarted | Recipients | A file upload has started and is incoming |
onFileAvailable | Recipients | File is ready to download |
// Send to everyone
window.EnxRtc.sendFiles(true, []);
// --- Sender event listeners ---
window.EnxRtc.addEventListner("onInitFileUpload", function(data) {
console.log("Upload started:", JSON.stringify(data.data));
});
window.EnxRtc.addEventListner("onFileUploaded", function(data) {
console.log("File uploaded successfully:", JSON.stringify(data.data));
});
window.EnxRtc.addEventListner("onFileUploadFailed", function(data) {
console.error("Upload failed:", JSON.stringify(data.data));
});
// --- Receiver event listeners ---
window.EnxRtc.addEventListner("onFileUploadStarted", function(data) {
console.log("Incoming file upload:", JSON.stringify(data.data));
});
window.EnxRtc.addEventListner("onFileAvailable", function(data) {
console.log("File ready to download:", JSON.stringify(data.data));
showDownloadPrompt(data.data);
});
| Error Code | Description |
|---|---|
| 5089 | Storage access denied |
| 5091 | File sharing is not available in this context |
| 1185 | File is too large; maximum allowed size exceeded |
| 1182 | Failed to upload the file |
Cancel a File Upload
Cancel a specific in-progress upload by its job ID, or cancel all active uploads at once.
// Cancel a single upload
window.EnxRtc.cancelUpload(jobId);
// Cancel all uploads
window.EnxRtc.cancelAllUploads();
// Event fired when an upload is cancelled
window.EnxRtc.addEventListner("onFileUploadCancelled", function(data) {
console.log("Upload cancelled:", JSON.stringify(data.data));
});
Download a Shared File
When onFileAvailable fires, the recipient knows a file is ready. Call
getAvailableFiles() to retrieve the full list of downloadable files, then call
downloadFile() to download a specific one.
// Step 1: Get all files available for download
window.EnxRtc.getAvailableFiles(
function(data) {
console.log("Available files:", JSON.stringify(data.data));
// data.data is an array of file info objects
},
function(err) { console.error("Error:", JSON.stringify(err)); }
);
// Step 2: Download a specific file
// fileInfo comes from onFileAvailable or getAvailableFiles
// isAutoSave: true = SDK saves file and returns path
// false = SDK returns raw Base64 data for manual saving
window.EnxRtc.downloadFile(fileInfo, true);
window.EnxRtc.addEventListner("onInitFileDownload", function(data) {
console.log("Download started:", JSON.stringify(data.data));
});
window.EnxRtc.addEventListner("onFileDownloaded", function(data) {
// data.data contains the file path (if autoSave=true) or Base64 data
console.log("Downloaded:", JSON.stringify(data.data));
});
window.EnxRtc.addEventListner("onFileDownloadFailed", function(data) {
console.error("Download failed:", JSON.stringify(data.data));
});
Cancel a File Download
// Cancel a single download
window.EnxRtc.cancelDownload(jobId);
// Cancel all active downloads
window.EnxRtc.cancelAllDownloads();
window.EnxRtc.addEventListner("onFileDownloadCancelled", function(data) {
console.log("Download cancelled:", JSON.stringify(data.data));
});
| Error Code | Description |
|---|---|
| 5089 | Storage access denied |
| 5090 | Failed to save file |
| 1183 | Failed to download file |
| 1181 | File download not available in this context |
sendUserData() lets you pass arbitrary structured data to one or more participants. The
EnableX server does not enforce any schema on the payload — you define the keys to match your
application's needs. Use this to build features like polling, raise-hand mechanisms, or any custom
workflow that requires passing data between participants.
- Method:
window.EnxRtc.sendUserData(message, isBroadcast, recipientIDs)
| Event | Fired To | Description |
|---|---|---|
onAcknowledgedSendData | Sender | Data was sent successfully |
onUserDataReceived | Recipients | Custom data received from another participant |
// Custom payload — define any structure you need
var message = {
sender: "John",
message: "Voting for you",
candidate: 5,
rating: 3
};
// Broadcast to everyone
window.EnxRtc.sendUserData(message, true, []);
// Or send to specific participants
window.EnxRtc.sendUserData(message, false, ["client_id_1", "client_id_2"]);
// Sender confirmation
window.EnxRtc.addEventListner("onAcknowledgedSendData", function(data) {
console.log("Data sent:", JSON.stringify(data.data));
});
// Receiving end
window.EnxRtc.addEventListner("onUserDataReceived", function(data) {
console.log("Custom data received:", JSON.stringify(data.data));
handleCustomSignal(data.data);
});
Annotation lets one participant draw and mark up another participant's video stream in real time. The annotator starts annotation on a target client's stream, and all participants in the room are notified.
Start Annotation
- Method:
window.EnxRtc.startAnnotation(clientId) - Parameter:
clientId— String. Client ID of the participant whose stream will be annotated
| Event | Fired To | Description |
|---|---|---|
onStartAnnotationAck | Annotator | Confirms annotation has started |
onAnnotationStarted | All participants | Notifies everyone that annotation is active |
window.EnxRtc.startAnnotation(clientId);
window.EnxRtc.addEventListner("onStartAnnotationAck", function(data) {
console.log("Annotation started (ack):", JSON.stringify(data.data));
showAnnotationToolbar();
});
window.EnxRtc.addEventListner("onAnnotationStarted", function(data) {
console.log("Annotation active (all):", JSON.stringify(data.data));
showAnnotationIndicator();
});
Stop Annotation
- Method:
window.EnxRtc.stopAnnotation()
| Event | Fired To | Description |
|---|---|---|
onStoppedAnnotationAck | Annotator | Confirms annotation has stopped |
onAnnotationStopped | All participants | Notifies everyone that annotation ended |
window.EnxRtc.stopAnnotation();
window.EnxRtc.addEventListner("onStoppedAnnotationAck", function(data) {
console.log("Annotation stopped (ack):", JSON.stringify(data.data));
hideAnnotationToolbar();
});
window.EnxRtc.addEventListner("onAnnotationStopped", function(data) {
console.log("Annotation ended (all):", JSON.stringify(data.data));
hideAnnotationIndicator();
});
Screen sharing publishes the device's screen as a video stream into the room at 6 fps. It carries on Stream ID 101 — other participants must subscribe to stream ID 101 to receive and display it.
settings.screen_share: true in
the Room Creation API payload.
Start Screen Sharing
- Method:
window.EnxRtc.addScreenShare(viewOptions, successCallback, errorCallback) - Event:
onScreenSharedStarted— notifies all participants that screen sharing has begun
var viewOptions = {
height: 130,
width: 100,
margin_top: 50,
margin_left: 0,
margin_right: 15,
margin_bottom: 10,
position: "top"
};
window.EnxRtc.addScreenShare(
viewOptions,
function(data) { console.log("Screen share started:", JSON.stringify(data.data)); },
function(err) { console.error("Error:", JSON.stringify(err)); }
);
// All participants (including presenter) receive this
window.EnxRtc.addEventListner("onScreenSharedStarted", function(data) {
console.log("Screen share active:", JSON.stringify(data.data));
// Subscribe to stream ID 101 to view the shared screen
subscribeToStream("101");
});
Stop Screen Sharing
removeScreenShare() explicitly to stop it.
- Method:
window.EnxRtc.removeScreenShare(successCallback, errorCallback) - Event:
onScreenSharedStopped— notifies all participants that screen sharing ended
window.EnxRtc.removeScreenShare(
function(data) { console.log("Screen share stopped:", JSON.stringify(data.data)); },
function(err) { console.error("Error:", JSON.stringify(err)); }
);
window.EnxRtc.addEventListner("onScreenSharedStopped", function(data) {
console.log("Screen share ended:", JSON.stringify(data.data));
removeScreenShare(); // Clean up the view
});
Canvas Streaming publishes any UI view into the room as a video stream. It is carried on Stream ID 102 — participants must subscribe to stream ID 102 to receive the canvas content.
settings.canvas: true in the
Room Creation API payload.
Start Canvas Streaming
- Method:
window.EnxRtc.addCanvasScreen(viewOptions, successCallback, errorCallback) - Event:
onCanvasStarted— notifies all participants that canvas streaming began
var options = {
height: 130,
width: 100,
margin_top: 50,
margin_left: 0,
margin_right: 15,
margin_bottom: 10,
position: "top"
};
window.EnxRtc.addCanvasScreen(
options,
function(data) { console.log("Canvas streaming started:", JSON.stringify(data.data)); },
function(err) { console.error("Error:", JSON.stringify(err)); }
);
window.EnxRtc.addEventListner("onCanvasStarted", function(data) {
console.log("Canvas active:", JSON.stringify(data.data));
// Subscribe to stream ID 102 to view the canvas
subscribeToStream("102");
});
Stop Canvas Streaming
- Method:
window.EnxRtc.removeCanvasScreen(successCallback, errorCallback) - Event:
onCanvasStopped— notifies all participants that canvas streaming ended
window.EnxRtc.removeCanvasScreen(
function(data) { console.log("Canvas stopped:", JSON.stringify(data.data)); },
function(err) { console.error("Error:", JSON.stringify(err)); }
);
window.EnxRtc.addEventListner("onCanvasStopped", function(data) {
console.log("Canvas ended:", JSON.stringify(data.data));
removeCanvasScreen(); // Clean up the view
});