get the socket name list in node.js - node.js

I am currently creating the chatting app.
I want to get the all the chat room list.
or else all the connedted socket's name list
//now in the room
socket.join(roomID); <--- want to get all connedted socket list
socket.nickname = name;
socket.roomIn = roomID;
socket.roomName = room;

List of all socket.io rooms (actually its a list of key,value pairs where the key is the room name and the value is the roomId:
io.sockets.adapter.rooms
List of all socket.io connections in a room:
io.sockets.clients( roomID );

Related

socket.io Rooms Connection Limitation

I have question about socket.io.
Is there a way to limit connections in rooms? I want to limit connections room to two users.
So that only the employer and the designer can talk.
To do this, you need some sort of identifier. If you have their username, you can just search for their username in some sort of Map containing username to the respective socket. Then, when you send a message you can use socket.to(anothersocket.id).emit("message", "message content). The other person will message to your socket.id. This is because all sockets are in the room of their id.
use this code and limit the user to join. I think this is the simplest way possible --->>>
io.on("connection", function (socket) {
console.log("User Connected :" + socket.id);
//Triggered when a peer hits the join room button.
socket.on("join", function (roomName) {
let rooms = io.sockets.adapter.rooms;
let room = rooms.get(roomName);
//room == undefined when no such room exists.
if (room == undefined) {
socket.join(roomName);
socket.emit("created");
} else if (room.size == 1) {
//room.size == 1 when one person is inside the room.
socket.join(roomName);
socket.emit("joined");
} else {
//when there are already two people inside the room.
socket.emit("full");
}
console.log(rooms);
});
});

How to get the client id?

I am using the ws lib and I want to make a private chat just like this: client A sends a message to client B.
There I have a ws.clients.forEach() method to broadcast to every client, but how can I get the client id of an individual one?
When you set up your chat system and userA wants to chat with userB, you have to have an identifier that userA users to tell the server they want to chat with userB. If the ws library doesn't provide an easy to use identifier for each connected user, then you need to assign one when the user connects to your server and then keep track of it for each connection in a way you can find the socket that has a given id. One simple way would be to just create a Map object where key is the ID and value is the socket. You can then lookup any socket by id.
For example, you could create a unique ID for each incoming socket connection and store it like this:
const uuid = require("uuid/v4");
const wss = new WebSocket.Server({ port: 8080 });
const idMap = new Map();
wss.on('connection', function connection(ws) {
// create uuid and add to the idMap
ws.uuid = uuid();
idMap.add(ws.uuid, ws);
ws.on('close', function() {
// remove from the map
idMap.delete(ws.uuid);
});
ws.on('message', function(info) {
try {
info = JSON.parse(info);
if (info.action = "send") {
let dest = idMap.get(info.targetId);
if (dest) {
dest.send(JSON.stringify({action: "message", sender: ws.uuid, data: info.message}));
}
}
} catch(e) {
console.log("Error processing incoming message", e);
}
});
});
Then, you could use that uuid value internally to identify which user someone wanted to connect to or send to.
In most real applications, you will also create some sort of login and username. A unique username could also be used as the id.

how does a user connected to a room using socket.io get the data that was send to the room before he joined it

a user joins a room and emits its username to the room using passport.socketio . With the help of socket.request.user.user_id i am able to get the user_id of the socket and fetch the username corresponding to user_id from the database.
function onNewplayer_GK (data) {
var room_id = find_Roomid_GK();
var room = room_List_GK[room_id];
//join the room
this.room_id = room_id;
this.join(this.room_id);
console.log("created new room with id " + room_id);
console.log("created new player with id " + this.id);
var user_id = this.request.user.user_id;
db.collection('user-details').findOne({_id:ObjectId(user_id)},(err,result)=>{
var results = JSON.stringify(result);
var results = JSON.parse(results);
console.log('name is'+ (results.user_name));
var name = results.user_name;
this.emit('myname',{
my_name:name
});
this.broadcast.to(room_id).emit('enemyname',{
enemy_name:name
});
});
io.on('connection',(socket)=>{
console.log('user connected ' + socket.id);
// listen for new player
// socket.on("new_player", onNewplayer);
socket.on('new_player_history',onNewplayer_history);
socket.on('new_player_GK',onNewplayer_GK);
find_Roomid_GK() is a function which looks for rooms which are not filled and if filled it will create a room and assigns it to room_id.There is no problem in the functionality of the rooms. I just want to emit both the user's usernames to each other. how?? I am unable to emit the first user connected username to the second user connected after the first.
But when another user connects and joins the same room, it is able to emit its details to the connected sockets. But this socket is not able to get the details of the sockets connected before this socket which is reasonable enough to understand.
Does anyone have an idea on how this newly connected socket will fetch the username of the connected sockets using passport.socketio ?

Node js chatting with multiple users in same room

I am new to node.js. I am creating a chat app. I want to manage 4 users who are connected to the room. I have the primary key of the logged in user User A in the session, I can also save it in hidden file. When the page loads I only have one socket connected to server (i.e. socket of User A). When user A wants to chat with User B, I have a textarea for message, a div to show the chat message history and one send button.
How can I allow user A to chat with N number of users and keep track of who's chatting who?
I am thinking of following method to keep track of the chat messages,
Save both users primary key in hidden fields. When user A send message
to User B. Send User A and B's PK to server along with message and
save it in database.
or...
Is there any way to identify User B's Socket. So that Saving/Handling
User A and B's primary on client side can be avoided.
You can broadcast the message to all connected users.
io.sockets.emit("method","Message");
or you can send message to the specific user socket
io.sockets.socket(socketId).emit("method","Message");
Also you can add the users to the specific room on connection
io.sockets.on('connection', function (socket) {
socket.join("RoomName");
});
and send message to the room ( Message will deliver to all joined users )
io.to('RoomName').emit("method","Message");
You can get the socket id of user on connection and save it to array or database .
io.sockets.on('connection', function (socket) {
console.log( "User connected on " + socket.id);
});
Chat Application :
Node.js is single thread application.So You will have all connected user socket object stored in the io.sockets
Step 1: Save socket id of user in to database on Connection
Step 2: Remove Socket id of user from database on connection
Step 3: if socket id of user exist in database then this mean user is connected and you can send the message to user socket.
Node.js
// User Socket array storage
var user_by_socket = [];
var socket_to_users = [];
io.sockets.on('connection', function (socket) {
// Save Socket Object
user_by_socket[socket.id] = socket;
socket_to_user["Jhon"] = socket;
user_by_socket[socket.id] = socket;
socket_by_user["David"] = socket;
//Send Message
socket.on('send',function(data){
// Sent by username
socket_by_user["David"].emit("recieve","{ "From" : 'Jhon' , 'message' : "Hello" }");
//Sent by Socket Id
user_by_socket["Socket ID"].emit("recieve","{ "From" : 'Jhon' , 'message' : "Hello" }");
});
});

Emit to socket with a particular object attribute

I am adding the username to the socket object like this which is working fine
socket.on('add user', function (username) {
socket.username = username;
});
Lets assume the username is khawer and now i want to emit to this socket where username is khawer but i am unable to do so.
I have tried this
io.sockets.connected[socket.username].emit('chat message', msg);
And this
io.sockets.sockets[socket.username].emit('chat message', msg);
But both did not work. What am i doing wrong here?
Just assigning a username property to a socket does not make it so that it's indexed by name - thus you cannot do either of the types of lookups you're doing.
If you want to find a socket by username, you will either have to do a brute force search of all the sockets to find the one that has the same user name or you will have to create your own index of sockets by name.
If you want to do a brute force lookup to find it, you could do this:
var list = io.sockets.sockets;
for (var i = 0; i < list.length; i++) {
if (list[i].username === "khawer") {
list[i].emit('chat message', msg);
}
}
You could also put each user into a chatroom with a name that matches their username. Then, you could send to any given username by simply sending to the chatroom by that name. You'd be using the chatroom feature as an index by username. It would just require one extra step to put a socket into a chatroom that matches their username when they connect.
Or, each time a socket connects and disconnects, you could maintain your own socket index by username (this is relatively common).

Resources