Utilizing Vue and Websockets for seamless communication: Managing the exchange of messages between users

In an attempt to create a messaging system that shows alerts of messages to different users, I have implemented Vue Socket Io from https://www.npmjs.com/package/vue-socket.io. However, the issue lies in the fact that the alerts are not being triggered as expected. Even though the client is successfully subscribed to an event in mounted, named after their userID, the message sent from the server does not display the alert.

Server:

io.on('connection', function(socket) {
    socket.on('sendMessage', function (data) {
       console.log("Sending message to" + data.user);
       socket.emit(`CHAT_${data.user}`, data.msg)
    });
 });

Client:

In the client side implementation, the userIDSelf is passed in as a prop indicating the logged-in user's ID. In the mounted() hook, the client subscribes to a custom chat channel with their userID appended to it.

mounted() {
    this.sockets.subscribe(`CHAT_${this.userIDSelf}`, (data) => {
         alert(data)
    });
}, 

Furthermore, there is a sendMessage() function which retrieves input values from two fields on the template. The first field requires the recipient's user ID while the second field contains the actual message. These values are then sent to the backend server.

methods: {
  sendMessage() {
        this.$socket.emit('sendMessage', {user:  this.userIDReceiver, msg: this.message})
  },
}

Answer №1

A certain issue arises from a logical standpoint in the server code presented here.

io.on('connection', function(socket) {
  socket.on('sendMessage', function (data) {
    console.log("Sending message to" + data.user);
    socket.emit(`CHAT_${data.user}`, data.msg)
  });
});

The problem lies in the fact that the socket representing User 123, who triggers the sendMessage event, is also expected to receive the emitted CHAT_456 event. However, User 123's socket specifically listens for CHAT_123 events. This results in the socket sending itself a message without being able to receive it.


Potential Resolutions

Solution A - Implementing the room Approach

Upon a socket connection to the server, organize it into a specific room based on its user id. To achieve this, ensure the userid is sent to the server during connection, possibly through a query parameter. On the client side, include a token query parameter in the connection string as follows:

const io = require('socket.io-client');
const socket = io("https://server-domain.com/?token=" + userid);

Then, instruct the connecting socket to join a room with the corresponding user id on the server side:

io.on('connection', function(socket) {
  const userid = socket.handshake.query.token;
  socket.join(userid);
});

Subsequently, the sendMessage functionality can be handled in this manner:

/* ... server side */
socket.on('sendMessage', function (data) {
  console.log("Sending message to" + data.user);
  io.to(data.user).emit('chatMessage', data.msg);
});

Solution B - Adopting the keep reference to the socket Strategy

Each socket internally possesses a unique socket id. While these IDs are typically hidden from users/clients, you do have access to distinct user ids. By establishing a relationship between user id / socket instance on the server side, you can retrieve the socket object associated with each user using their user id.

One simplistic approach involves maintaining an in-memory store on the server side:

let socketRefs = {};
io.on('connection', function(socket) {
  const userid = socket.handshake.query.token;
  socketRefs[userid] = socket;
});

This enables the handling of sendMessage in the following way:

/* ... server side */
socket.on('sendMessage', function (data) {
  console.log("Sending message to" + data.user);
  let targetSocket = socketRefs[data.user];
  targetSocket.emit('chatMessage', data.msg);
});

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

Issue encountered when summing numbers: There appears to be a continuous loop updating within a component's rendering function

Let's say I have a variable initialized as 0 and a method that increments this variable... However, when I try to use them, an error message is displayed: [Vue warn]: You may have an infinite update loop in a component render function. Here is the ...

The scale line on the OpenLayers map displays the same metrics twice, even when the zoom level is different

When using the Openlayers Map scale line in Metric units, a specific zoom rate may be repeated twice during the zoom event, even though the actual zoom-in resolution varies on the map. In the provided link, you can observe that the zoom rates of 5km and ...

Having trouble with tabs in jQuery?

I'm having trouble setting up tabs in a reservation form with 3 tabs that include text boxes for user input. I can't seem to get it working properly and I'm not sure where I've gone wrong. Could it be due to the placement of the content ...

Connect to the Kendo dropdown list undefined

I am looking to automatically bind a model to a Kendo dropdown list. The model is retrieved from the server and can sometimes be undefined or a valid object. My problem arises when the value is undefined. In this case, Kendo selects the first item in the ...

Is there a way to customize the selected option in the autocomplete feature of Material UI components?

Is it possible to customize the CSS of selected options in Material UI autocomplete? Can this be achieved by utilizing the theme? ...

React - The `component` prop you have supplied to ButtonBase is not valid. Please ensure that the children prop is properly displayed within this customized component

I am attempting to use custom SVG icons in place of the default icons from Material UI's Pagination component (V4). However, I keep encountering this console error: Material-UI: The component prop provided to ButtonBase is invalid. Please ensure tha ...

Select the send all text option when making a request

Using ajax, I can dynamically fill a drop-down select menu. My next step is to include all the text from the selected options in my request. <select name=".." > <option value="0"> ... </option> <option value="1"> xxx </option ...

Error message: A boolean type cannot be used as a function in the fullcalendar ajax call

I have successfully implemented a fullcalendar into my app and have added a method to filter results by user: function filterEventsByProvider(selected_provider) { $('#calendar').fullCalendar('removeEvents'); $('#calendar&a ...

Tips for changing array items into an object using JavaScript

I am working with a list of arrays. let arr = ["one","two"] This is the code I am currently using: arr.map(item=>{ item }) I am trying to transform the array into an array of sub-arrays [ { "one": [{ ...

Is it possible to align an entire column to the right in the Material UI Data Grid?

I'm currently exploring Material UI and grappling with a specific challenge. Is there a method within Material UI to create a Data Grid with two columns, one left-aligned and the other right-aligned? I've managed to align the headers as desired, ...

Using object syntax in React state management

I've been working on dynamically updating the state in my React app, and this is what the current state looks like: this.state = { title: "", image: "", imageFile: "", formTitle: "", formMessage: "", formImage: "", ...

Verify if the radio element is marked as selected in the AJAX reply

My ajax response contains two radio elements and I need to check if they are checked in the response. I've tried using the code below to check the radio status but it's not working: $('#input[type=radio]').each(function(){ alert($( ...

Switch between selection modes in React JS DataGrid using Material UI with the click of a button

I've been working on creating a datagrid that includes a switch button to toggle between simple and multiple selection modes. const dispatch = useDispatch(); const { selectedTransaction } = useSelector(...) const [enableMultipleSelection, setEnableMu ...

The "keydown" event in React will not alter the state

I am currently developing an application that requires me to track the keys pressed by the user. I am utilizing keydown and keyup events for this purpose. However, I am facing a challenge where I do not want the same key to be registered multiple times whe ...

Transforming an ordinary JavaScript object into a class instance

As I was delving into Angular's documentation on "Interacting with backend services using HTTP", I came across the following statement in the "Requesting a typed response" section: ...because the response is a plain object that cannot be automatical ...

What could be the reason for the counter not being incremented when the button is clicked

While attempting to increase the counter in my test, I encountered an issue where pressing the button did not change the value. I tried using both fireEvent from React testing library and React test utils, but the value remained at 10. My project is using ...

Display information from an array in checkboxes. If the same data appears in another array, the corresponding checkbox in React will be automatically checked

I currently have two arrays. The first array, let's call it arr1, contains multiple objects such as [{"Name":"Mr.X"},{"Name":"Mr.Y"},{"Name":"Mr.Z"}]. The second array, named arr2, holds a few values like [{"Name":"Mr.Z"}]. My goal is to display all ...

The issue of an undefined Node.js variable post "await"

While I know similar questions have been asked before, I assure you that I've gone through them; however, I'm still facing a challenge. I have a simple code snippet to retrieve a token for a 3rd-party API service: let tok = ''; const g ...

Trouble with AJAX Post Request: Missing JSON Response

Below is the AJAX request I have created: var data = modalDom.find("form").serializeObject(); data["returnJson"] = true; $.ajax({ type: "POST", url: "/companies/edit/", data: data, dataType: "JSON", success: function (result) { ...

Unexpected values being returned by Javascript/jQuery variables

Struggling with understanding scope in JavaScript, like many others before me. It can be quite challenging to navigate through the code at times. I've reviewed previous discussions on this topic, but I'm still having trouble applying it to my spe ...