How to add rooms in Node.js with Socket.io? - javascript

I have been following up many articles to learn making chat application with Node.js and Socket.io. Everything is clear and I can make an application moving messages from client to server and emitting to all etc but only one thing is not clearing and cannot figure this out.
How can I add rooms to io.sockets.manager.room?
What is the code to add rooms to sockets.manager? The most simple and thorough article I found is http://udidu.blogspot.com/2012/11/chat-evolution-nodejs-and-socketio.html but after a long struggle I still could not find where the author adds new rooms to server.

io.sockets.manager.room
returns list of rooms. Your question is not correct. You don't add rooms to io.sockets.manager.room instead you make a socket join a room and that room is added to io.sockets.manager.room.
To make a socket join a room use this:
io.sockets.on('connection', function(socket){
var room = 'Your room name';
socket.room = room;
socket.join(room);
socket.on('disconnect', function(){
socket.leave(socket.room);
});
});

There is a easier way to do I think.
io.on("connection",socket => {
socket.on("joined", (username, room) => {
server.join(room)
io.to(room).emit("joined",username")
})
})

Related

Ideal way to handle multiple socket rooms?

So I am creating a chat application and I want to handle multiple chat rooms. Now I watched some tutorials and came up with a way.
const io = require("socket.io")(http);
io.on("connection", (socket) => {
socket.on("joinRoom", (roomid) => {
//Joining the room
socket.join(roomid)
//Broadcasting all previous messages
io.to(roomid).emit("messages",allPreviousMessages)
})
socket.on("chatMessage", (data) => {
//Saving msg to dB then broadcasting
io.to(roomid).emit("message",receivedMessage)
})
socket.on("disconnect",(data) => {
//updating user's lastSeen info in dB
})
})
So on my frontend when user clicks on a chatroom we call the "joinRoom" event and connect to the room and on clicking another chatroom make the same process of joining room.
Is this an ideal way for handling multiple chatrooms? If not so please let me know a better solution.
I think the best way to implement private rooms or channels or chats is this way. I have implemented an example for these three sections. Link
User token and api must be authenticated before connecting to socket.io. If this part is ok it will connect to socket.io otherwise it can't cause you to see the event that is there. Something happens by calling each of them. For example, by calling this onNotificationForVoiceCall event, the received data is first checked, then it is checked whether this user is present in the list of online users or not, and the state of the next step is checked. Whether or not this room has already been created in the database, the response of all these operations is returned to the user by socket.emit,
And I fixed some bug in project.

socket io not emitting messages to rooms

I have been stuck with this problem for a while now . I want to emit to all the connected clients of a room when a new client joins the room. I have already seen the https://socket.io/docs/v3/emit-cheatsheet/index.html and tried all the emit methods for rooms as seen below in server code and none of them work except the one which emits to all the connected clients and not to a specific room.
Server code
socket.on("newUser", (data) => {
socket.join(data.sessionId);
//not a single one of these works to emit to a specific room
socket.broadcast.to(data.sessionId).emit("userJoin", data);
io.to(data.sessionId).emit("userJoin", data);
io.in(data.sessionId).emit("userJoin", data);
io.sockets.in(data.sessionId).emit("userJoin", data);
//only this works but send to all the clients
io.emit("userJoin", data);
});
client code
//simply adds a div with info to inform other users that a new user has joined
//works only on io.emit() which emits to all the connected clients of every room
socket.on("userJoin",(data)=>{
const users=document.getElementById('users');
const noUsers=document.getElementById('noUsers');
if(data.action==='join'){
const user = document.createElement('article');
user.classList.add('card');
user.classList.add('lobby-item');
user.innerHTML=`<header class='card__header'>
<h1 class='session__id'>
${data.user.name}
</h1>
</header>`;
users.appendChild(user);
}
});
I think the problem with all the room emit methods not working might be with the rooms being formed wrongly or are empty.But still none of the methods for rooms work here.
Don't process overlep the socket event name and Check that the data object was sent correctly
example
io.to(data.sessionId).emit("userRoomJoin", data);
io.emit("userJoin", data);
Split the socket event name.
If it still doesn't work.
console.log(data.sessionId);
Check that the data object was not undefinded.
when you use an object into your code try to check is it undefinded or no !
so try this command :
console.log(data);
In socket io if there is a redirect from the app or a refresh from the client there is a new socket.id created which means that the old socket was disconnected and a new one was created.
In my app i was first doing socket.emit() on the join in route and then redirecting the user to a different lobby route which meant that the socket which joined the room had been disconnected due to redirecting it to lobby and a new socket was created which wasn't in any room.
Therefore io.to(data.sessionId).emit() wasn't working as all the socket that joined the room were disconnected due to redirecting. io.emit() works as it emits to all the sockets that are currently connected

How can i send data to u particular user using socket.io

i am building a mobile app with ionic, i am using socket.io, i want to be able to send message to a particular user with an id, and not broadcast the message to everyone, the chat application is not a chat room style kind of app but a one on one chatting app like watsapp, i searched online but what i saw was not working, here is the code for the server side
const io = require('socket.io')(server);
io.on('connection', socket => {
console.log('New user connected');
socket.on('get_all_msg', data => {
DBConn.query(`SELECT * FROM chats WHERE rec_id = ? || send_id=?`, [data.id, data.id], (error, results, fields) => {
if (error) throw error;
io.to(data.id).emit('all_msg', results)
});
})
})
the id of the user i am chatting with is the data.id, i tried using io.to(data.id).emit('all_msg', results) but the user did not receive any message, pls what am i doing that is not right
Here's the client side code
this.socket.emit('get_all_msg', {id:this.contactInfo.id})
this.service.socket.fromEvent('all_msg').subscribe((data:any) => {
console.log(data)
})
I am using ngx-socket.io in my ionic add
we need to map socket id to user id;
we can solve this using redis but simple way i did was
actually socket io itself joins the current into a room with its id(socketio) itself;
i was like, "why not join that socket into room with user_id"
backend side:
io.on('connection',socket=>{
socket.on('join-me',userid=>{
socket.join(userid);
})
})
front end side:
const socket=io(`blahblah`);
socket.on('connect',()=>{
socket.emit('join-me',current_user_id);
})
when one user emits new-message event
we can get the participent id's and can simply loop over their ids and emit an event
socket.on('message',data=>{
//do some logic let say
participents=data.participents;
parsedMessage=someLogic(data);
for(id of participents){
//here is the magic happens io.to(room_id) here room id is user id itself.
io.to(id).emit('new-message',parsedMessage);
}
})
works with one to one and group chat!

How to socket.io with express generator? Individual socket, for individual link

I have typical express-generator app. In my controllers folder I have code:
router.get('/:id([A-Za-z0-9_]{5,25})', function(req, res, next) {
res.render('my-page.html', { title: 'Messages'});
//How to implement socket.io code for this page?
/*
io.on('connection', function(socket){
console.log('a user connected');
});
*/
});
I tried simple guide from socket.io website and from stackoverflow advices, but it isn't working.
Try to imagine, that here is many different chat rooms, and for every room, I need to open individual socket... I know how to make it global, but have no idea, how to make personal socket, for personal page...
That's what rooms are made for.
socket.join(<ROOM_NAME>)
If you'd like to join a room, named for URL you got connected from, you can use socket.request.url. For instance:
io.sockets.on('connection', (socket) =>
{
const _req = socket.request
console.log(_req.url) // do something with it
}
edit
and do not put socket.io logic in your REST route. Make one, global connection logic, which you can (obviously) make modular.

How to check how many participants are connected to my chat room using socket IO [duplicate]

This question already has answers here:
getting how many people are in a chat room in socket.io [duplicate]
(8 answers)
Closed 6 years ago.
Here is an excerpt of the code I am using to make a connection to my chat room...
io.on('connection', function(socket) {
var col = db.collection('messages');
sendStatus = function(s){
socket.emit('status', s);
};
//emit all messages
col.find().limit(100).sort({_id:1}).toArray(function(err, res){
if(err) throw err;
socket.emit('output', res);
});
socket.on('input', function(data) {
...
... etc
What code can I implement to check how many users or participants are connected to my chat room.
I heard of a method clients() but I'm not sure if that's what I need to use or how to use it.
In the latest version of socket.io, you can see how many sockets are in a given chat room with this:
io.sockets.adapter.rooms["testRoom"].length
Where testRoomis whatever the name of your chat room is (whatever you used .join() with.
io.sockets.adapter.rooms["testRoom"]
is an Object where each property name except .length is the socket.id of the socket that is in the chat room.
FYI, the code you show in your question doesn't appear to have anything to do with socket.io chat rooms so that has me a bit perplexed.

Categories