Setting up WebSocket in DronaHQ
The challenge begins with a fundamental need for real-time data across diverse applications, whether this be live updates for cryptocurrency prices, shares on the stock or even sensor readings from IoT devices and live messages in a chat program—solved in a way that does not require refreshing the entire page over and over or complicated backend design to pull new data. You can do this with DronaHQ Global JS Objects and WebSocket support.
In this blog, we will learn how to utilize WebSocket connections in DronaHQ to create an interactive dashboardfor real-time data.
By tapping into the flexibility of Global JS Objects, you can define reusable functions and variables that power seamless live data updates across your applications. Developers looking to boost user engagement, or professionals looking to build dashboards for real-time monitoring, this project demonstrates how WebSockets and DronaHQ can be a game-changer.
What the WebSocket project is about
- Real-time data streaming:
The project focuses on connecting DronaHQ apps to WebSocket endpoints, such as Binance’s WebSocket API, to fetch live data and display it instantly. This eliminates delays and provides users with up-to-the-second information. - Dynamic and reusable design:
The WebSocket connection logic is encapsulated in reusable Global JS Objects, which can be called from any app within the DronaHQ account. This ensures that developers can set up similar projects with minimal effort. - Interactive user interface (UI):
The UI of the project is designed to display live trade data for cryptocurrencies (e.g., Bitcoin, Ethereum) or any other data stream. It updates dynamically as new data is received, creating an engaging user experience.
What are Global JS objects?
DronaHQ’s Global JS Objects allow you to define functions and variables that can be accessed globally within your account. These objects can be used in various contexts such as Data Binding, Event Actions, JS Transform, and other places that support JavaScript. Once saved, the objects are accessible from any app, enabling seamless reuse across your applications.
Key benefits:
- It consists of reusable JavaScript functions and variables.
- Extend them globally and across all apps.
- Improve code flexibility and reduce code redundancy.
User interface (UI) overview
- Table grid for real-time data:
- Purpose: The table grid is the central component of the UI. It displays the live trade data for the selected symbol.
- Columns in the Table Grid:
- Symbol: The trading pair (e.g., BTCUSDT for Bitcoin to USDT).
- Time: The exact timestamp of the latest trade, formatted to the user’s local time.
- Price: The live price of the asset or data point, updated in real-time.
- Behavior: Whenever a new trade or update is received via WebSocket, the table grid updates automatically without requiring a page reload.
- Start/stop WebSocket buttons:
- Purpose: Allows users to start or stop the WebSocket connection.
- Start Button: Initiates the WebSocket connection for the entered symbol and begins streaming live data to the table grid.
- Stop Button: Safely closes the WebSocket connection and clears the table grid.
- Input Field for Symbol Selection:
- Purpose: Enables the user to enter the trading pair (e.g., BTCUSDT) or any relevant identifier required to connect to the WebSocket endpoint.
- Behavior: The entered symbol is passed to the
startWebSocket
function, which uses it to establish a connection.
WebSocket implementation
WebSockets allow for full-duplex communication channels over a single TCP connection, allowing a server to push data to a client when it is available, making this technology best suited for use cases such as financial dashboards, chat applications, or IoT dashboards that require real-time updates at all times. In DronaHQ, the WebSocket connections are useful in building dynamic interfaces, which will get updated instantly without refreshing or polling.
To know more about the working of WebSockets with DronaHQ, click here. Below is an example of how to set up a WebSocket connection using Global JS Objects.
Code Walkthrough
let socket = null; // Store the WebSocket connection
let tableData = {}; // Object to store the latest data for the symbol
// Function to display messages in the console
function logToConsole(message) {
console.log(message);
}
// Function to start WebSocket connection for a single symbol
function startWebSocket(symbol) {
const streamUrl = `wss://stream.binance.com:9443/ws/${symbol}@trade`; // WebSocket URL for the symbol
socket = new WebSocket(streamUrl);
socket.addEventListener("open", () => {
logToConsole(`Connected to WebSocket for ${symbol}.`);
});
socket.addEventListener("message", (event) => {
const data = JSON.parse(event.data);
const price = parseFloat(data.p).toFixed(2); // Extract price
const symbol = data.s.toUpperCase(); // Symbol (e.g., BTCUSDT)
const time = new Date(data.T).toLocaleTimeString(); // Time (formatted)
// Log received message details
logToConsole(`Received data for ${symbol}: Time - ${time}, Price - $${price}`);
// Update tableData with the latest trade data for the symbol
tableData[symbol] = {
time: time,
price: `$${price}`,
};
const temp = [{
time: time,
price: `$${price}`,
}];
// Log the updated table data to the console
logToConsole(`Updated tableData for ${symbol}:`, temp);
// Set the updated table data in the control
UTILITY.SETCTRLVALUE([{ name: "tablegrid", value: temp }]);
});
socket.addEventListener("error", (error) => {
logToConsole(`WebSocket Error for ${symbol}: ${error.message}`);
});
socket.addEventListener("close", () => {
logToConsole(`WebSocket connection closed for ${symbol}.`);
});
}
// Function to stop the WebSocket connection
function stopWebSocket() {
if (socket) {
logToConsole("Closing WebSocket connection...");
socket.addEventListener("close", () => {
logToConsole("WebSocket connection confirmed closed.");
});
socket.addEventListener("error", (error) => {
logToConsole(`Error while closing WebSocket: ${error.message}`);
});
socket.close();
socket = null;
logToConsole("WebSocket connection stopped.");
} else {
logToConsole("No active WebSocket connection to stop.");
}
}
// Export the functions to DronaHQ
const ExportModule = {
startWebSocket: startWebSocket,
stopWebSocket: stopWebSocket,
};
Explanation:
- Start WebSocket
This functionality connects to a specific symbol’s data stream and listens for real-time trade data. It dynamically updates the UI usingUTILITY.SETCTRLVALUE
, ensuring that users see the latest information without manual intervention.
Click here to learn more about usingUTILITY.SETCTRLVALUE
and other utility methods in DronaHQ. - Stop WebSocket
ThestopWebSocket
function safely terminates the active WebSocket connection and nullifies the reference to the WebSocket instance. This helps prevent resource leaks and ensures that no unwanted data continues to flow into the app.
Data queries setup
In DronaHQ, you can use the startWebSocket
and stopWebSocket
functions in Data Queries to integrate WebSocket functionality into your apps. Below are two queries:
Explanation of WebSocket queries
- Start WebSocket Query
Thestart_websocket
query is designed to establish a WebSocket connection for a specific data stream. It takes a symbol as a parameter (e.g., a cryptocurrency pair like BTCUSDT or a stock ticker) and initiates the WebSocket connection to receive real-time updates for that symbol. - Stop WebSocket Query
Thestop_websocket
query is responsible for safely closing the active WebSocket connection. In addition, it resets the associated data grid in the UI, ensuring that no outdated or unnecessary information is displayed after the connection is terminated.
async function JSCode(output) {
if (typeof Formbuilder == "undefined") {
JSOBJECTS.stopWebSocket();
}
UTILITY.SETCTRLVALUE([{ name: "tablegrid", value: [] }]);
return output;
}
Trigger WebSocket
To integrate WebSocket functionality into your app, you need to configure triggers through the Action Flow of button controls.
Here’s a step-by-step breakdown to configure the Trigger actions:
- Navigate to the Action Flow for the button controls (e.g., Start, Cancel) in your app.
- Add a Data and Keyword action for Run Data Query.
- From the drop-down list, select the data query that was pre-configured and hit Save.
- Repeat this for both the Open and Close buttons, ensuring each button is linked to its respective data query.
How it works
- Start the WebSocket Connection:
- When you preview the application, enter the desired currency pair in the input field and click the Start button.
- This triggers the Open button’s data query, which establishes the WebSocket connection.
- Fetch and Update Data:
- Once the connection is established, the system will fetch the details of the currency pair you specified. These details are passed as arguments to the WebSocket connection.
- Using a utility function, the data fetched from the WebSocket is then used to dynamically update the table grid control, which is populated with the latest currency pair data.
- Continuous Data Update:
- Since WebSocket operates as a continuous, real-time connection, the system will keep fetching and displaying the updated currency data. The table grid will automatically refresh every time new data arrives.
- This process ensures that the table reflects the most current data without any manual refresh.
- Close the Connection:
- When you’re finished and want to stop receiving data, simply click the Cancel button.
- This action triggers the Close button’s data query, which disconnects the WebSocket and halts the continuous data updates.
Key considerations:
- Your Practice: Validate and Secure All Your Custom Code
- Close WebSocket connections properly to avoid resource leaks.
This project showcases the power of WebSockets in creating highly interactive and real-time applications using DronaHQ. The intuitive UI, combined with reusable JavaScript code, makes it easy for developers to implement live data streaming for various use cases. By following this guide, you can build robust, scalable, and responsive apps that meet modern user expectations for real-time interactivity.