skip to Main Content

when i run the code, the server server side receive the message but the client side doesnt get anything until they send message. however in html doesnt show anything wrong

i have this server code:

var http = require('http').Server(app);
var io = require('socket.io')(http);
var cors = require('cors')
const { socket } = require('socket.io');

io.on('connection', () =>{
  console.log('a user is connected')
  
})

i have this route:

var http = require('http').Server(router);
var io = require('socket.io')(http);

// Render Message
router.get('/messages/:id', async function (req, res, next) {
    user = await User.findOne({_id: req.session.userId},  {username: 1})
    return res.render("user/messages.ejs", {user: user, booking: req.params.id});
});

// Display Message from DB
router.get('/messageslist/:booking', (req, res) => {
    Message.find({booking: req.params.booking})
    .populate({
        path: "pro",
        model: Pro,
    }).populate({
        path: "user",
        model: User,
    }).exec().then((data) => {
        res.json(data)
    })
    
})
router.post('/messages', async (req, res) => {
    const {booking, user, message} = req.body;
    try {
        var msg = new Message({
            booking: booking,
            message: message,
            user: user
        });
        var savedMessage = await msg.save()
        console.log('saved');
        io.emit('message', req.body);
        res.sendStatus(200);
    } catch (error) {
        res.sendStatus(500);
        return console.log('error', error);
    } finally {
        console.log('Message Posted')
    }
})

this is my html:

var socket = io();
    $(() => {
      $("#send").click(() => {
        sendMessage({
          booking: $("input[name=booking]").val(),
          user: $("input[name=user]").val(),
          message: $("#message").val()
        });
      })
      getMessages()
    })

    socket.on('message', addMessages) 

    function addMessages(message) {
      if (message.user && message.user != '') {
        if ($("input[name=user]").val() == message.user._id) {
          html = '<div class="msg right-msg"><div class="msg-img" style="background-image: url(' + message.user.image +
            ')"></div>'
          html += '<div class="msg-bubble"><div class="msg-info"><div class="msg-info-name">' + message.user.username +
            '</div><div class="msg-info-time">' + message.createdAt + '</div></div>'
        }
      } else {
        html = '<div class="msg left-msg"><div class="msg-img" style="background-image: url(' + message.pro.image +
          ')"></div>'
        html += '<div class="msg-bubble"><div class="msg-info"><div class="msg-info-name">' + message.pro.username +
          '</div><div class="msg-info-time">' + message.createdAt + '</div></div>'
      }
      html += '<div class="msg-text">' + message.message + '</div></div></div>'
      window.scrollTo(0, document.body.scrollHeight);
      $("#msger-chat")+$(".msger-chat").append(html)
    }
    function getMessages() {
      $.get('http://127.0.0.1:3000/messageslist/<%=booking%>', (data) => {
        data.forEach(addMessages);
      })

    }
    function sendMessage(message) {
      $.post('http://127.0.0.1:3000/messages', message)
    }

When i run it, my server outputs: User connected and message saved;. But my client doesn’t get a response

it will show like this

2

Answers


  1. On the client side where you listen for sockets, you do not pass reference to the function. 2nd argument is callback function that has received data as parameter and you should call addMessage from inside. Here is the example code:

    socket.on('message', (data) => {
      addMessages(data)
    }) 
    

    Just update this in front end code and it should work

    Login or Signup to reply.
  2. I think the problem is you are creating two io instances. One in server code

    var http = require('http').Server(app);
    var io = require('socket.io')(http);
    var cors = require('cors')
    const { socket } = require('socket.io');
    
    io.on('connection', () =>{
      console.log('a user is connected')  
    })
    

    another one is in route handlers

    var http = require('http').Server(router);
    var io = require('socket.io')(http);
    

    You should have a singleton io object which is responsible to handle all the activities. This is an approach how to create such design. you will have mainSocketServer

    createSocketServer = (server) => {
      // this is how you implemented
      var io = require('socket.io')(http);
      // this is the part to create singleton object
      serverStore.setSocketServerInstance(io);
      
      io.on("connection", (socket) => {
        // this socket obj will include
    

    about connected user. this socket is actually connected user client
    console.log(‘a user is connected’)

    socket.on("direct-message", (data) => {
      // you create socket events handler in different file
      directMessageHandler(socket, data);
    }); });};
    
    module.exports = {
       createSocketServer,
    };
    

    you need another file where you store all the connected users. usually in socket server, users are stored in a Map

    const connectedUsers = new Map();
    let activeRooms = [];
    
    let io = null;
    
    // we call this in mainSocketServer file
    const setSocketServerInstance = (ioInstance) => {
      io = ioInstance;
    };
    // you export this and use it anywhere on your server
    const getSocketServerInstance = () => {
      return io;
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search