End of Life for Twilio Programmable Video - Upgrade to VideoSDKLearn More

How to Build OpenFire WebRTC App with JavaScript?

Learn how to create a real-time communication app using OpenFire and WebRTC. This comprehensive guide covers installation, configuration, and implementation steps with code examples to help you get started.

Introduction to OpenFire WebRTC Technology

What is OpenFire WebRTC?

In today's digital landscape, real-time communication (RTC) has become an integral part of various applications, enabling instant interaction through video, voice, and data sharing. OpenFire, an open-source XMPP (Extensible Messaging and Presence Protocol) server, offers a robust platform for real-time collaboration and communication. When integrated with WebRTC (Web Real-Time Communication), OpenFire transforms into a powerful RTC server capable of supporting seamless, peer-to-peer communication directly through web browsers.
WebRTC is a groundbreaking technology that provides web applications and websites with the ability to capture, and possibly broadcast, audio and/or video media. It also facilitates the direct exchange of any type of data between browsers, without requiring an intermediary. This makes it ideal for applications that need real-time audio and video communication, such as video conferencing, file sharing, and instant messaging.

Benefits of Integrate OpenFire with WebRTC

  1. Scalability: OpenFire can manage thousands of simultaneous connections, making it suitable for large-scale applications.
  2. Flexibility: Being open-source, OpenFire allows extensive customization to meet specific requirements.
  3. Security: OpenFire supports encrypted connections, ensuring that the communication remains private and secure.
  4. Interoperability: WebRTC supports various web browsers and platforms, ensuring wide accessibility.
By leveraging OpenFire with WebRTC, developers can create applications that facilitate real-time communication with high performance and reliability. Whether for business collaboration tools, customer service solutions, or social media platforms, the combination of these technologies provides a solid foundation for building advanced communication features.
In the following sections, we will dive into the technical aspects of setting up and developing an OpenFire WebRTC application, providing detailed steps, code snippets, and best practices to help you get started.

Getting Started with the Code

Create a New OpenFire WebRTC App

Embarking on the journey of creating a real-time communication application with OpenFire and WebRTC begins with setting up a new project. This section will guide you through the essential steps, from installation to structuring your project.

Install OpenFire

To get started, you need to install OpenFire on your server. Follow these steps to ensure a smooth installation:

[a] Download OpenFire

Visit the

OpenFire download page

and download the latest version suitable for your operating system.

[b] Install OpenFire

Follow the installation instructions provided for your operating system. For example, on a Linux system, you can use the following commands:


1    wget https://download.igniterealtime.org/openfire/openfire_4.6.4_all.deb
2    sudo dpkg -i openfire_4.6.4_all.deb

[c] Configure OpenFire

Once installed, you can access the OpenFire administration console by navigating to http://your_server:9090. Follow the setup wizard to complete the basic configuration, including setting the admin password and configuring the database.

Structure of the Project

With OpenFire installed, the next step is to structure your WebRTC project. A well-organized project structure facilitates easier development and maintenance. Here’s a recommended directory structure for your OpenFire WebRTC project:
2├── src/
3│   ├── main/
4│   │   ├── java/
5│   │   └── resources/
6│   ├── test/
7│   └── webapp/
8├── config/
9│   ├── openfire.xml
10│   └── webrtc-config.json
11├── scripts/
12│   ├── start.sh
13│   └── stop.sh
14└── README.md
  • src/main/java: Contains the Java source code for your application.
  • src/main/resources: Stores the resource files needed by your application.
  • src/test: Holds the test cases for your application.
  • src/webapp: Contains the web application files, including HTML, CSS, and JavaScript.
  • config: Directory for configuration files such as openfire.xml and webrtc-config.json.
  • scripts: Shell scripts to manage your application, including startup and shutdown scripts.

App Architecture

Understanding the architecture of your OpenFire WebRTC application is crucial for effective development. Here’s an overview of the components involved:
  1. OpenFire Server: Acts as the signaling server to manage connections and message exchanges.
  2. WebRTC API: Handles the real-time media streams and peer-to-peer data channels.
  3. Client Application: The front-end application, typically built using HTML, CSS, and JavaScript, interacts with the OpenFire server and uses the WebRTC API for real-time communication.
The OpenFire server is responsible for user authentication, session management, and message routing. The WebRTC API handles the media capture, encoding, and transmission between clients. The client application presents the user interface and integrates the WebRTC functionality to enable real-time audio, video, and data communication.
In the upcoming sections, we will delve into the specific steps required to configure your OpenFire server, wireframe the UI components, and implement the core functionalities of your WebRTC application. This comprehensive approach will equip you with the knowledge to build a robust OpenFire WebRTC application from scratch.

Step 1: Get Started with Configuration

Initial Setup

Before diving into the development of your OpenFire WebRTC application, it's crucial to configure the server and ensure that it is ready to handle WebRTC connections. Proper configuration will enable smooth communication between clients and the server.

Configuration Files

Start by setting up the necessary configuration files. Two key files need to be configured:
  1. openfire.xml: This file contains the primary configuration settings for your OpenFire server.
  2. webrtc-config.json: This file holds the configuration settings specific to WebRTC.
Example openfire.xml snippet:


2    <!-- Network settings -->
3    <network>
4        <interface></interface>
5        <port>5222</port>
6        <securePort>5223</securePort>
7    </network>
8    <!-- Admin console settings -->
9    <adminConsole>
10        <port>9090</port>
11        <securePort>9091</securePort>
12    </adminConsole>
13    <!-- Database settings -->
14    <database>
15        <defaultProvider>
16            <driver>com.mysql.cj.jdbc.Driver</driver>
17            <serverURL>jdbc:mysql://localhost:3306/openfire</serverURL>
18            <username>openfire</username>
19            <password>password</password>
20        </defaultProvider>
21    </database>
Example webrtc-config.json snippet:


2    "iceServers": [
3        {
4            "urls": ["stun:stun.l.google.com:19302"]
5        },
6        {
7            "urls": ["turn:turnserver.example.com"],
8            "username": "user",
9            "credential": "pass"
10        }
11    ],
12    "room": "myroom",
13    "maxParticipants": 10

Server Configuration

To configure the OpenFire server for WebRTC, follow these steps:

[a] Enable WebSockets

WebRTC requires WebSocket connections for signaling. Ensure that WebSockets are enabled on your OpenFire server.
1- Navigate to the OpenFire admin console.
2- Go to `Server` > `Server Settings` > `HTTP Binding`.
3- Enable the `Client to Server` WebSocket and set the port to `7070`.

[b] Install Plugins

OpenFire offers various plugins to extend its functionality. For WebRTC, you need to install the appropriate plugins.
1- Go to `Plugins` > `Available Plugins` in the OpenFire admin console.
2- Install the `WebRTC` plugin, which provides the necessary support for WebRTC functionalities.

[c] Configure Security

Ensure secure communication by configuring SSL/TLS.
1- Go to `Server` > `Server Settings` > `Security Settings`.
2- Configure the `Client Connection Security` to require encrypted connections.

[d] Create Users and Groups

Set up user accounts and groups to manage permissions and access control.
1- Go to `Users/Groups` > `Users` in the OpenFire admin console.
2- Create new users and assign them to relevant groups.

Testing the Configuration

After completing the initial setup and configuration, it's essential to test the server to ensure everything is working correctly.

Check Server Status

Verify that the OpenFire server is running and accessible.
1- Navigate to `Server` > `Server Information` in the OpenFire admin console.
2- Ensure that all services are running correctly.

Connect a Client

Use a basic XMPP client to connect to the OpenFire server and test the connection.
1- Install an XMPP client like Pidgin or Spark.
2- Configure the client to connect to your OpenFire server using the credentials you created earlier.

Test WebRTC Signaling

Ensure that the WebRTC signaling is working by using a WebRTC test page.
1- Create a simple HTML page that connects to the OpenFire server and initiates a WebRTC connection.
2- Use the browser console to verify that WebRTC signaling messages are being exchanged correctly.
By following these steps, you will have a properly configured OpenFire server ready to handle WebRTC connections. In the next part, we will focus on designing the user interface and wiring up all the necessary components for your WebRTC application.

Step 2: Wireframe All the Components

Creating a user-friendly interface is crucial for the success of your OpenFire WebRTC application. In this section, we will focus on designing and wireframing the necessary UI components, ensuring that each part of the application is well-structured and intuitive for users.

Designing the User Interface

The user interface (UI) for your WebRTC application needs to be simple yet effective, providing users with easy access to all essential features. Here's a breakdown of the primary UI components you should include:
  1. Join Screen: A screen where users can enter their credentials and join a meeting.
  2. Main Conference Screen: The main interface for the video call, displaying video streams and controls.
  3. Control Panel: A panel with buttons for various controls like mute, unmute, and video toggle.
  4. Participant List: A section displaying the list of participants currently in the call.
  5. Chat Box: An area for text chat during the video call.

Component Breakdown

Join Screen

The join screen is the first point of interaction for users. It should be straightforward, allowing users to quickly enter their name and join the conference.
HTML Code Snippet:


1<div id="join-screen">
2    <h2>Join Meeting</h2>
3    <input type="text" id="username" placeholder="Enter Your Name" />
4    <button id="join-btn">Join</button>

Main Conference Screen

Once the user joins the meeting, they are taken to the main conference screen. This screen should display video streams, a control panel, a participant list, and a chat box.
HTML Code Snippet:


1<div id="conference-screen">
2    <div id="video-streams">
3        <video id="video1" autoplay></video>
4        <video id="video2" autoplay></video>
5        <!-- Additional video elements -->
6    </div>
7    <div id="controls">
8        <button id="mute-btn">Mute</button>
9        <button id="unmute-btn">Unmute</button>
10        <button id="video-off-btn">Video Off</button>
11        <button id="video-on-btn">Video On</button>
12    </div>
13    <div id="participants">
14        <h3>Participants:</h3>
15        <ul id="participant-list">
16            <li>User 1</li>
17            <li>User 2</li>
18            <!-- Additional participants -->
19        </ul>
20    </div>
21    <div id="chat-box">
22        <h3>Chat:</h3>
23        <input type="text" id="chat-input" placeholder="Enter message here" />
24        <button id="send-btn">Send</button>
25    </div>

Integrating the Components

Once you have the wireframes and HTML structure ready, the next step is to integrate these components into your application. This involves writing the necessary JavaScript code to handle user interactions and WebRTC functionality.
JavaScript Code Snippet:


1document.getElementById('join-btn').addEventListener('click', function() {
2    const username = document.getElementById('username').value;
3    if (username) {
4        joinConference(username);
5    } else {
6        alert('Please enter your name');
7    }
10function joinConference(username) {
11    // Code to join the WebRTC conference
12    document.getElementById('join-screen').style.display = 'none';
13    document.getElementById('conference-screen').style.display = 'block';
14    // Additional WebRTC setup code
17// Example of adding participants to the list dynamically
18function addParticipant(name) {
19    const participantList = document.getElementById('participant-list');
20    const listItem = document.createElement('li');
21    listItem.textContent = name;
22    participantList.appendChild(listItem);
25// Example of handling chat messages
26document.getElementById('send-btn').addEventListener('click', function() {
27    const message = document.getElementById('chat-input').value;
28    if (message) {
29        sendMessage(message);
30        document.getElementById('chat-input').value = '';
31    }
34function sendMessage(message) {
35    // Code to send the chat message
By wireframing and designing the key components of your OpenFire WebRTC application, you ensure a structured and user-friendly interface. In the next part, we will implement the join screen functionality, providing users with a seamless experience as they enter their credentials and join the meeting.

Step 3: Implement Join Screen

The join screen is a critical component of your OpenFire WebRTC application, as it is the first interaction point for users. This section will guide you through the process of creating a user-friendly join screen, implementing user authentication, and ensuring a seamless entry into the conference.

Creating the Join Screen

To begin, we'll create a simple HTML form that allows users to enter their name and join the meeting. This form will be the starting point for users to authenticate and connect to the OpenFire server.
HTML Code for Join Screen:


1<!DOCTYPE html>
2<html lang="en">
4    <meta charset="UTF-8">
5    <meta name="viewport" content="width=device-width, initial-scale=1.0">
6    <title>Join Meeting</title>
7    <style>
8        #join-screen {
9            text-align: center;
10            margin-top: 50px;
11        }
12        #join-screen input, #join-screen button {
13            padding: 10px;
14            margin: 5px;
15        }
16    </style>
19    <div id="join-screen">
20        <h2>Join Meeting</h2>
21        <input type="text" id="username" placeholder="Enter Your Name" />
22        <button id="join-btn">Join</button>
23    </div>
24    <script src="join.js"></script>

User Authentication

To authenticate the user and establish a connection with the OpenFire server, we will implement the necessary JavaScript functions. These functions will handle user input, validate the entered name, and initiate the WebRTC connection process.
JavaScript Code for Join Screen (join.js):


1document.getElementById('join-btn').addEventListener('click', function() {
2    const username = document.getElementById('username').value;
3    if (username) {
4        joinConference(username);
5    } else {
6        alert('Please enter your name');
7    }
10function joinConference(username) {
11    // Simulate user authentication and connection to OpenFire server
12    console.log(`User ${username} is attempting to join the conference...`);
14    // Placeholder for actual OpenFire authentication and WebRTC setup
15    authenticateUser(username)
16        .then(() => {
17            console.log(`User ${username} authenticated successfully.`);
18            // Proceed to conference screen
19            window.location.href = 'conference.html';
20        })
21        .catch(error => {
22            console.error('Authentication failed:', error);
23            alert('Failed to join the conference. Please try again.');
24        });
27function authenticateUser(username) {
28    // Simulated authentication process
29    return new Promise((resolve, reject) => {
30        setTimeout(() => {
31            if (username) {
32                resolve();
33            } else {
34                reject('Invalid username');
35            }
36        }, 1000);
37    });

Integrating with OpenFire

To integrate the join screen with OpenFire, you need to ensure that the server is ready to handle authentication requests. OpenFire supports various authentication mechanisms, including plain text, SASL, and external databases. For simplicity, we will simulate the authentication process in this example.

Implementing Secure Authentication

In a production environment, you should implement secure authentication mechanisms to protect user credentials and ensure secure communication with the OpenFire server. Here’s an example using SASL for secure authentication:
Updated JavaScript Code for Secure Authentication:'


1function authenticateUser(username) {
2    return new Promise((resolve, reject) => {
3        // Replace with actual authentication logic
4        fetch('https://your-openfire-server/auth', {
5            method: 'POST',
6            headers: {
7                'Content-Type': 'application/json'
8            },
9            body: JSON.stringify({ username })
10        })
11        .then(response => response.json())
12        .then(data => {
13            if (data.success) {
14                resolve();
15            } else {
16                reject('Authentication failed');
17            }
18        })
19        .catch(error => {
20            reject(error);
21        });
22    });

Transition to Conference Screen

Upon successful authentication, the user should be redirected to the main conference screen. Create a new HTML file for the conference screen and update the JavaScript code to handle the transition.
HTML Code for Conference Screen (conference.html):


1<!DOCTYPE html>
2<html lang="en">
4    <meta charset="UTF-8">
5    <meta name="viewport" content="width=device-width, initial-scale=1.0">
6    <title>Conference</title>
7    <style>
8        /* Add necessary styles for the conference screen */
9    </style>
12    <div id="conference-screen">
13        <h2>Welcome to the Conference</h2>
14        <!-- Add video streams, controls, participant list, and chat box here -->
15    </div>
16    <script src="conference.js"></script>
By following these steps, you have successfully implemented the join screen for your OpenFire WebRTC application. Users can now enter their name, authenticate, and join the conference seamlessly. In the next part, we will focus on implementing the main conference screen, including video streams, controls, and participant management.

Step 4: Implement Controls

Implementing a robust set of controls is essential for enhancing the user experience in your OpenFire WebRTC application. These controls will allow users to manage their audio and video settings, enabling or disabling their microphone and camera, as well as other advanced features such as screen sharing and recording. This section will guide you through the implementation of these controls.

Basic Controls

The basic controls include functionalities such as mute, unmute, video on, and video off. These controls are fundamental for managing the media streams during a WebRTC session.
HTML Code for Controls:


1<div id="controls">
2    <button id="mute-btn">Mute</button>
3    <button id="unmute-btn">Unmute</button>
4    <button id="video-off-btn">Video Off</button>
5    <button id="video-on-btn">Video On</button>

JavaScript for Basic Controls

To make these buttons functional, we need to write JavaScript that interacts with the WebRTC API. This code will manage the local media streams and toggle the media tracks accordingly.
JavaScript Code for Basic Controls:


1let localStream;
3navigator.mediaDevices.getUserMedia({ video: true, audio: true })
4    .then(stream => {
5        localStream = stream;
6        document.getElementById('video1').srcObject = localStream;
7    })
8    .catch(error => {
9        console.error('Error accessing media devices.', error);
10    });
12document.getElementById('mute-btn').addEventListener('click', () => {
13    localStream.getAudioTracks()[0].enabled = false;
14    console.log('Audio muted');
17document.getElementById('unmute-btn').addEventListener('click', () => {
18    localStream.getAudioTracks()[0].enabled = true;
19    console.log('Audio unmuted');
22document.getElementById('video-off-btn').addEventListener('click', () => {
23    localStream.getVideoTracks()[0].enabled = false;
24    console.log('Video turned off');
27document.getElementById('video-on-btn').addEventListener('click', () => {
28    localStream.getVideoTracks()[0].enabled = true;
29    console.log('Video turned on');

Advanced Controls

For a more feature-rich application, you can implement advanced controls such as screen sharing and recording. These features can significantly enhance the usability of your WebRTC application.

Screen Sharing

Screen sharing allows users to share their screen with other participants in the call. This feature is particularly useful for presentations and collaborative work.
HTML Code for Screen Sharing:


1<button id="share-screen-btn">Share Screen</button>
JavaScript Code for Screen Sharing:


1document.getElementById('share-screen-btn').addEventListener('click', () => {
2    navigator.mediaDevices.getDisplayMedia({ video: true })
3        .then(screenStream => {
4            let screenTrack = screenStream.getVideoTracks()[0];
5            screenTrack.onended = () => {
6                // Handle screen share ending
7                console.log('Screen sharing stopped');
8            };
10            // Replace the video track in the local stream with the screen track
11            let sender = peerConnection.getSenders().find(s => s.track.kind === 'video');
12            sender.replaceTrack(screenTrack);
13            console.log('Screen sharing started');
14        })
15        .catch(error => {
16            console.error('Error sharing screen.', error);
17        });


Recording the call can be an essential feature for users who need to review the session later. WebRTC allows recording media streams using the MediaRecorder API.
HTML Code for Recording:


1<button id="start-recording-btn">Start Recording</button>
2<button id="stop-recording-btn">Stop Recording</button>
JavaScript Code for Recording:


1let mediaRecorder;
2let recordedChunks = [];
4document.getElementById('start-recording-btn').addEventListener('click', () => {
5    mediaRecorder = new MediaRecorder(localStream);
6    mediaRecorder.ondataavailable = event => {
7        if (event.data.size > 0) {
8            recordedChunks.push(event.data);
9        }
10    };
11    mediaRecorder.onstop = () => {
12        let blob = new Blob(recordedChunks, { type: 'video/webm' });
13        let url = URL.createObjectURL(blob);
14        let a = document.createElement('a');
15        a.style.display = 'none';
16        a.href = url;
17        a.download = 'recording.webm';
18        document.body.appendChild(a);
19        a.click();
20        URL.revokeObjectURL(url);
21    };
22    mediaRecorder.start();
23    console.log('Recording started');
26document.getElementById('stop-recording-btn').addEventListener('click', () => {
27    mediaRecorder.stop();
28    console.log('Recording stopped');

Integrating Controls with UI

Ensure that the controls are seamlessly integrated with the user interface. This involves placing the buttons in an easily accessible location and ensuring that the UI updates reflect the current state of the media streams.
Updated HTML for Main Conference Screen:


1<div id="conference-screen">
2    <div id="video-streams">
3        <video id="video1" autoplay></video>
4        <!-- Additional video elements -->
5    </div>
6    <div id="controls">
7        <button id="mute-btn">Mute</button>
8        <button id="unmute-btn">Unmute</button>
9        <button id="video-off-btn">Video Off</button>
10        <button id="video-on-btn">Video On</button>
11        <button id="share-screen-btn">Share Screen</button>
12        <button id="start-recording-btn">Start Recording</button>
13        <button id="stop-recording-btn">Stop Recording</button>
14    </div>
15    <!-- Other components like Participants and Chat -->
By implementing these controls, you have equipped your OpenFire WebRTC application with essential features that enhance user interaction and experience. Users can now manage their audio and video settings, share their screens, and record sessions. In the next part, we will focus on implementing the participant view, allowing users to see and interact with other participants in the call.

Get Free 10,000 Minutes Every Months

No credit card required to start.

Step 5: Implement Participant View

The participant view is a critical component of any WebRTC application. It allows users to see and interact with other participants in the call. This section will guide you through the implementation of a dynamic participant view, where video streams from all participants are displayed and managed effectively.

Displaying Participants

To display the video streams of all participants, we need to dynamically create and manage video elements for each participant. The WebRTC API provides the necessary functionality to handle multiple peer connections and streams.
HTML Structure for Participant View:


1<div id="conference-screen">
2    <div id="video-streams"></div>
3    <div id="controls">
4        <button id="mute-btn">Mute</button>
5        <button id="unmute-btn">Unmute</button>
6        <button id="video-off-btn">Video Off</button>
7        <button id="video-on-btn">Video On</button>
8        <button id="share-screen-btn">Share Screen</button>
9        <button id="start-recording-btn">Start Recording</button>
10        <button id="stop-recording-btn">Stop Recording</button>
11    </div>
12    <div id="participants">
13        <h3>Participants:</h3>
14        <ul id="participant-list"></ul>
15    </div>
16    <div id="chat-box">
17        <h3>Chat:</h3>
18        <input type="text" id="chat-input" placeholder="Enter message here" />
19        <button id="send-btn">Send</button>
20    </div>

JavaScript for Managing Participants

We need to handle the addition and removal of participants dynamically. This involves creating video elements for each participant and updating the UI accordingly.
JavaScript Code for Participant Management:


1let localStream;
2let peerConnections = {};
3const videoContainer = document.getElementById('video-streams');
4const participantList = document.getElementById('participant-list');
6navigator.mediaDevices.getUserMedia({ video: true, audio: true })
7    .then(stream => {
8        localStream = stream;
9        addVideoStream('local', stream);
10    })
11    .catch(error => {
12        console.error('Error accessing media devices.', error);
13    });
15function addVideoStream(id, stream) {
16    const videoElement = document.createElement('video');
17    videoElement.id = id;
18    videoElement.srcObject = stream;
19    videoElement.autoplay = true;
20    videoContainer.appendChild(videoElement);
22    const listItem = document.createElement('li');
23    listItem.id = `participant-${id}`;
24    listItem.textContent = id;
25    participantList.appendChild(listItem);
28function removeVideoStream(id) {
29    const videoElement = document.getElementById(id);
30    if (videoElement) {
31        videoElement.remove();
32    }
34    const listItem = document.getElementById(`participant-${id}`);
35    if (listItem) {
36        listItem.remove();
37    }
40// Example of handling a new participant joining
41function handleNewParticipant(id, stream) {
42    if (!peerConnections[id]) {
43        peerConnections[id] = stream;
44        addVideoStream(id, stream);
45    }
48// Example of handling a participant leaving
49function handleParticipantLeave(id) {
50    if (peerConnections[id]) {
51        removeVideoStream(id);
52        delete peerConnections[id];
53    }

Integrating with WebRTC Signaling

To manage participants in a real-world scenario, you need to integrate with the WebRTC signaling server (OpenFire in this case). This involves listening for signaling messages that indicate when new participants join or leave the call.
JavaScript Code for WebRTC Signaling Integration:


1const socket = new WebSocket('wss://your-openfire-server/ws');
3socket.onopen = () => {
4    console.log('Connected to the signaling server');
5    socket.send(JSON.stringify({ type: 'join', name: 'local' }));
8socket.onmessage = (message) => {
9    const data = JSON.parse(message.data);
10    switch (data.type) {
11        case 'new-participant':
12            handleNewParticipant(data.id, data.stream);
13            break;
14        case 'participant-left':
15            handleParticipantLeave(data.id);
16            break;
17        // Handle other signaling messages
18    }
21function handleNewParticipant(id, stream) {
22    const peerConnection = new RTCPeerConnection();
23    peerConnections[id] = peerConnection;
25    peerConnection.ontrack = (event) => {
26        addVideoStream(id, event.streams[0]);
27    };
29    stream.getTracks().forEach(track => {
30        peerConnection.addTrack(track, stream);
31    });
33    // Exchange ICE candidates
34    peerConnection.onicecandidate = (event) => {
35        if (event.candidate) {
36            socket.send(JSON.stringify({ type: 'candidate', candidate: event.candidate, id: id }));
37        }
38    };
40    // Create and send an offer to the new participant
41    peerConnection.createOffer()
42        .then(offer => peerConnection.setLocalDescription(offer))
43        .then(() => {
44            socket.send(JSON.stringify({ type: 'offer', offer: peerConnection.localDescription, id: id }));
45        });
48socket.onclose = () => {
49    console.log('Disconnected from the signaling server');

Managing Participant Layout

To ensure a clean and user-friendly layout, you need to manage the arrangement of video streams dynamically. This involves resizing and positioning the video elements based on the number of participants.
CSS for Dynamic Layout:


1#video-streams {
2    display: flex;
3    flex-wrap: wrap;
4    justify-content: center;
7#video-streams video {
8    margin: 5px;
9    border: 1px solid #ccc;
10    width: 30%;
11    height: auto;
JavaScript for Dynamic Layout:


1function updateLayout() {
2    const videos = document.querySelectorAll('#video-streams video');
3    const count = videos.length;
5    videos.forEach(video => {
6        video.style.width = count > 2 ? '30%' : '45%';
7    });
10// Call updateLayout whenever participants are added or removed
11function handleNewParticipant(id, stream) {
12    // Existing code...
13    updateLayout();
16function handleParticipantLeave(id) {
17    // Existing code...
18    updateLayout();
By implementing the participant view, you have created a dynamic and interactive user interface for your OpenFire WebRTC application. Users can now see and interact with other participants, enhancing the overall communication experience. In the next part, we will focus on running and testing your code to ensure everything works as expected.

Step 6: Run Your Code Now

Testing Your Application

After implementing all the core features of your OpenFire WebRTC application, it's essential to test it thoroughly to ensure that everything works as expected. This section will guide you through running and testing your application.

[a] Start the OpenFire Server

Ensure your OpenFire server is up and running.


1    sudo systemctl start openfire

[b] Deploy Your WebRTC Application

Place your web application files (HTML, CSS, JavaScript) on a web server. You can use a simple HTTP server for testing purposes.


1    python3 -m http.server 8000

Open Your Application in the Browser

Navigate to http://localhost:8000 in your web browser to access your WebRTC application.

Join the Meeting

Enter your name on the join screen and click "Join" to enter the conference.

Test Media Streams

Ensure that your video and audio streams are working correctly. Test the mute, unmute, video off, and video on controls.

Test Advanced Features

Verify that screen sharing and recording functionalities are working as expected.

Check Participant View

Join the meeting from multiple devices to test the participant view. Ensure that new participants' video streams are displayed correctly and that the layout adjusts dynamically.

Troubleshooting Common Issues

Even with careful implementation, you might encounter some common issues. Here are a few tips to troubleshoot them:

No Video or Audio

Ensure that the browser has permission to access the camera and microphone. Check the console for any errors related to getUserMedia.

Connection Issues

Verify that your OpenFire server is accessible and that WebSockets are enabled. Check for network-related issues that might be blocking the connection.

Participant View Not Updating

Ensure that your signaling server (OpenFire) is correctly sending messages when participants join or leave. Check the console for any signaling errors.

Screen Sharing Not Working

Ensure that the browser supports the getDisplayMedia API. Check for any errors related to screen sharing permissions.

Recording Issues

Verify that the MediaRecorder API is supported by the browser. Check the console for any errors during the recording process.


Congratulations! You have successfully built and tested your OpenFire WebRTC application. Your application now supports real-time audio and video communication, screen sharing, recording, and a dynamic participant view. This comprehensive guide has provided you with the knowledge to create a robust and feature-rich WebRTC application using OpenFire.

Want to level-up your learning? Subscribe now

Subscribe to our newsletter for more tech based insights