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

Creating flexible Vue routes using a single router component and a navigational menu

I am working on a Vue project and I want to implement nested routes in my router.js. My goal is to have just one menu for all the nested routes and only one <router-view></router-view> in a master component. This is what I envision (in pseudoc ...

Unable to locate item by its identification number

Search for results in the index and return them. Method: async fetchIndex(req,res){ const userResults = await Usuario.find(); res.json(userResults); }, Route: routes.get('/api/usuarios', Usuario.fetchIndex); Having trouble ...

Conflicting Angular controller names within different modules

I'm facing an issue where two modules (A and B) with controllers of the same name are conflicting when imported into module C. Is there a recommended solution to prevent this conflict, such as using a naming convention like "module.controller" for ea ...

Displaying API response array object in React application

Currently, I am attempting to retrieve information from an API, parse the response content, and then display it in a loop. However, I have encountered a warning message: webpackHotDevClient.js:138 ./src/App.js Line 20: Expected an assignment or function ...

The first argument in the Node.appendChild function does not adhere to the Node interface when trying to append to a new element

Hey there, I'm new to web development and could use some help. I'm encountering an error where I am trying to add an href attribute to an image tag. Here is my code: function linkus() { var a = document.getElementsByTagName("img"); ...

Tips for generating a fixed-length array from multiple arrays with different lengths, focusing on selecting items from each array according to their significance

In order to create a quiz, I am looking to extract 'questions' from various 'topic' arrays. These topics are selected based on the user's preference and are used to populate a question bank for a 20-question quiz. The topics rated ...

Having trouble creating a text channel in discord.js

Today I successfully programmed a bot to respond to the "!new" command, but encountered an unexpected issue. The current functionality of the bot creates a channel named "support-1" when prompted with the "!new" command. However, every subsequent use of th ...

What is the process for requiring web workers in npm using require()?

I have a setup using npm and webpack, and a part of my application requires Web Workers. The traditional way to create web workers is by using the syntax: var worker = new Worker('path/to/external/js/file.js'); In my npm environment, this metho ...

Module not found: The system encountered an error and was unable to locate the file 'os' in the specified directory

I'm currently working on a Laravel/Vue3 project and ran into an issue. When I try to execute "npm run dev", I encounter 37 error messages. I suspect it has something to do with the mix or webpack configuration, but being unfamiliar with this area, I&a ...

Setting a default value in a multi-select dropdown using react-select

I have taken over management of my first React app, and I am facing a seemingly simple change that needs to be made. The modification involves an email signup page where users can select their interests from a multi-select dropdown menu. My task is to mak ...

Using a custom attribute in jQuery allows conditional statements to be executed using the

I have been attempting to create an if/else statement in jQuery using a custom attribute called "data-id". I decided to name it this way because I thought I could utilize the .data() method in jQuery, but unfortunately, it did not work as expected. Below ...

JavaScript Promise Chains- Issues with Functionality?

Could someone provide an explanation for why calling secondMethod in the Promise chain yields results, while calling secondMethod() does not? function firstFunction() { return new Promise(function(resolve, reject){ setTimeout(function() { ...

How can you make the table rows in jQuery scroll automatically while keeping the table header fixed in

Many solutions exist for making the header fixed and the table scrollable using code samples or plugins. However, my specific goal is to have the table data rows scroll automatically once they are loaded while keeping the header fixed in place. Is there a ...

Accessing an object from an AngularJS controller in an external function

I previously inquired about this issue and received a suggestion to add a service, but it did not solve the problem. I am trying to access a variable from a controller ($scope) within an external function. Below is a snippet of the example: app.controll ...

I'm so confused about the operation of each method in this context

I am experimenting with a simple process involving setTimeout function. My goal is to make the letters of a name appear individually and gradually at different times. For example, if the name is NAZ, I want the letters to appear in this order: first N, the ...

What steps can I take to fix the Error with webpack's style hot loader JavaScript?

Just starting out with native script and encountered an issue when running this code: <template> <view class="container"> <text class="text-color-primary">My Vue Native Apps</text> </view> </template> &l ...

What can I do to keep my navbar on top of the slideshow?

Is there a way to create a responsive navbar that sits in front of a slideshow containing images? I attempted to place the div within the main, but unfortunately it was unsuccessful. ...

Mysterious sayings encircling the words fetched through ajax

If the localhost is pointing to the folder named www, where the structure looks like: www/ file/test.cpp index.html I want to dynamically load the content of test.cpp into index.html and display it with the help of highlight.js. Below is the cod ...

Issue with pop-up functionality on web page using HTML, CSS, and JavaScript

Recently, I created a unique popup using HTML. You can see the complete code (excluding CSS) here: https://codepen.io/nope99675/pen/BawrdBX. Below is the snippet of the HTML: <!DOCTYPE html> <html> <head> <meta charset=&quo ...

Vue CLI-generated project experiencing issues with embedding Font Awesome code

After setting up a Vue project using the Vue CLI, I received an embed code for Font Awesome 5 in my email. I proceeded to insert this code into the index.html file located in the public folder of my project. <head> <script src="https://use.font ...