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
2
Answers
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:
Just update this in front end code and it should work
I think the problem is you are creating two
io
instances. One in server codeanother one is in route handlers
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
about connected user. this socket is actually connected user client
console.log(‘a user is connected’)
you need another file where you store all the connected users. usually in socket server, users are stored in a Map