Guide on implementing websocket as a functional API

I am facing an issue with my websocket connection between the client (browser) and server. Sometimes when I request data through the websocket, I struggle to efficiently manage my code due to its event-based nature.

When I send a websocket message in a function, I then have to listen for and handle it in the event listener. This creates a disconnect between the request and response handling in my code.

For example:

const ws = new WebSocket("ws://whatever");

function handleClickBtn() {
  ws.send('request something');
  // cannot get response here
}

ws.onmessage = function (event) {
  console.log(`response comes here: ${event.data}`);
}

It feels like a challenge to maintain this code structure compared to using REST API with async/await syntax for easier handling of requests and responses. Are there any techniques that could be applied here to improve this situation?

Answer №1

To effectively handle multiple asynchronous requests simultaneously, it is crucial to establish a system that correlates incoming responses with the corresponding previous requests. One approach is to assign unique identifiers to each request and ensure that the response includes the same identifier. For instance:

Request:

[82512903521, "fetch-data", "param1", "param2"]

Response:

[82512903521, {"some": "returned", "data": ...}]

Internally, you can maintain a list of sent request ids along with their associated callback functions, which will be executed upon receiving the matching response. This can be implemented as follows:

const requests = {};

function request(callback, ...params) {
    const id = randomId();
    ws.send([id, ...params])
    requests[id] = callback;
}

ws.onmessage = function (event) {
    const [id, data] = event.data;
    requests[id](data);
}

Various protocols and libraries, such as WAMP, already incorporate this mechanism for efficient handling of asynchronous operations.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Warning: Electron alert - Function _crypto.default.randomFillSync unavailable

I am trying to implement notifications in my Electron project on a Node server. To do this, I have installed the node-notifier module in my app folder using the following command: $ npm install --save node-notifier After installation, I added a button t ...

Exploring the process of transferring a jQuery array from a Rails controller to a PostgreSQL array column

For my project, I successfully pass a JavaScript array to a Rails controller using AJAX. The JavaScript array consists of upload image names. Within my postgresql database, there is an array column called "images." In the Rails controller, I attempted the ...

A guide on setting local storage using selenium and node.js

My goal is to use nodeJs + selenium to set local storage. I had success doing this with Java + Selenium using the code below: JavascriptExecutor js = (JavascriptExecutor) driver; js.executeScript("localStorage.setItem(arguments[0],arguments[1])", ...

Creating executable files from a node.js application: a step-by-step guide

I developed a custom node application that I usually run by executing the following command: node.exe app.js inputArg Is there a method to create a standalone .exe file for my application? So instead of the above command, I can simply run: App.exe input ...

Creating a personalized Material UI theme for enhancing the appearance of a Next.js App Router

Recently transitioned from C# development to diving into Next.js for a client project. Utilizing MUI, I have put in a day of work so far, resulting in a relatively small project. While I grasp the concept of SSR (Server-Side Rendering) theoretically, the ...

"Exploring the Latest Features of NextJS 13: Enhancing Server

Currently, I am in the process of familiarizing myself with NextJS 13 and its new APP folder structure. I am facing a challenge in updating data on server components without needing to reload the page or the app. My HomePage server component fetches a list ...

The instanceof operator does not recognize the value as an instance and is returning false, even though it

Is there a method to verify the current instance being used? This is what I am logging to the console: import { OrthographicCamera } from 'three'; // Later in the file: console.log(camera instanceof OrthographicCamera, camera); and the result ...

Click to trigger image rotation with JavaScript

img { display: block; margin: 20px; width: 50px; height: 50px; } .crossRotate { -webkit-transition-duration: 1s; -moz-transition-duration: 1s; -o-transition-duration: 1s; transition-duration: 1s; -webkit-transition-property: -webkit-tran ...

Encountering an error when trying to destructure a property of null

The concept of destructuring is fascinating, but I have been facing some challenges when trying to destructure nested objects. Consider the following code snippet: const { credit: { amount }, } = userProfile This can be risky because if the &ap ...

What is the process of creating a MaterialUI checkbox named "Badge"?

Badge API at https://material-ui.com/api/badge/ includes a prop called component that accepts either a string for a DOM element or a component. In my code: <Badge color="primary" classes={{ badge: classes.badge }} component="checkbox"> <Avatar ...

Unlocking the Power of jQuery's toggle Method for Dynamic Functionality

For my project, I require numerous jQuery toggles to switch between text and icons. Currently, I am achieving this by using: $("#id1").click(function () { //Code for toggling display, changing icon and text }); $("#id2").click(function () { //Same co ...

Can Firebase data be updated in real-time in a Vue app?

Utilizing Firebase for Authentication and integrating a database into a Vue app, my current task involves monitoring changes within a 'friends' collection specific to a user. The objective is to seamlessly display the list of friends while refle ...

Issue with compound key lookup functionality in mongoDB not functioning as expected

I am looking to conduct a join based on orderNo and articleCode within the details section (in both orderList and orderHistory) using aggregation methods. orderList: { "orderNo": "0000004680", "details": [{ "arti ...

How to resolve the error of "Objects are not valid as a React child" in NextJs when encountering an object with keys {children}

I am currently working on a nextjs application and I have encountered an issue with the getStaticPaths function. Within the pages folder, there is a file named [slug].tsx which contains the following code: import { Image } from "react-datocms"; i ...

Having Trouble with Finding Visible Divs?

Below is the code snippet I am working with: var len = $(".per:visible").length; $("#add-person").click(function(){ if ($(".persons div:visible").next().is(':hidden')){ $(".persons div:visible").next().slideDown('slow' , ...

Gather various input files to attach to FormData

Imagine having a scenario where you have the following form. <form id="testForm"> <input type="file" name="uploads[]"><br/> <input type="file" name="uploads[]"><br/> <input type="file" name="uploads[]"><br/> ...

The error message "data.map is not a function" is thrown in the getStatic

I am currently working on a blog project using Strapi in conjunction with Next.js My goal is to create dynamic pages by utilizing [id].js within the pages/posts/[id].js structure However, I've encountered an issue while attempting to map through the ...

Timing issues with setInterval and setTimeout are causing them to execute at the incorrect moments

I am struggling with changing the background image using setInterval and setTimeout every x seconds. The issue I am facing is that the timer is not working as intended, causing images to change instantly instead. let images = ['background1.jpg&apo ...

Ways to utilize gulp-rigger

When I include a .coffee file in a .js file, the gulp-rigger compiles it "on the fly" and concatenates it. Is there a way to pass parameters like { bare : true }? It seems to only work with default settings. Does anyone have experience using this plugin ...

Different ways of manipulating images with JavaScript

I attempted to tackle the issue independently, but I'm stumped. Is there a way to adjust the width of an image in JS when the screen dimensions are changed? ...