Socket.io Trouble with Emit - javascript

I'm trying to make a WebSocket server with Socket.io. When a new socket joins a room, I want to notify all the other sockets and also retrieve a list of sockets in the room for the new joiner.
socket.to(room).emit() seems to send to everyone in the room, but the documentation says socket.to().emit() should send to everyone but the sender. Is this correct?
namespace.on('connection', (socket) => {
socket.on('join-lobby', (pkg) => {
socket.join(pkg.lobbyid);
var x = Array.from(namspace.adapter.rooms.get(pkg.lobbyid));
1. socket.emit('joined-lobby', {players:x});
2. socket.to(pkg.lobbyid).emit('player-join', {joiner:socket.id});
// socket.to sends to sender as well??
});
}
This is what I have on the server side. That socket should only receive the 'joined-lobby' emission (1), all others should receive the 'player-join' emission (2).

Related

WebSocket replies to each client 'onConnect' with node.js

I have a ws.on('connection') event on my server which sends a JSON object to each connected client on their first connection.
However because of this bit:
// Sending the payload to all clients.
wss.clients.forEach((client) => {
// Prepare for transmission.
let transmission = JSON.stringify(SocketObject.query());
// Debug
console.log('[server:onConnection:init]');
// Send the transmission.
client.send(transmission);
});
Every time a client connects, the JSON object is transmitted to every client again and again. Is it possible to limit this reply to only the client that is getting connected initially?
It was my mistake, so when wrapped like this:
wss.on('connection', (ws) => {
console.log('[server:onConnection]');
ws.send('FIRST_RESPONSE');
... it does exactly what I need it to do. Meaning it only sends the message to the connected client. I don't know why I had the forEach(client) bit in there.

How to create dynamic socket rooms using socket.io

I want to implement multiple chat using socket.io can, iwas able to implement one to one chat using one socket.room but i want to create multiple socket rooms to chat with multiple people parallel
below is the example i got in git but i was not able to understand that how it will work for multiple chat can any one explain
Server side
io = socketio.listen(server);
// handle incoming connections from clients
io.sockets.on('connection', function(socket) {
// once a client has connected, we expect to get a ping from them
saying what room they want to join
socket.on('room', function(room) {
socket.join(room);
});
});
// now, it's easy to send a message to just the clients in a given
room
room = "abc123";
io.sockets.in(room).emit('message', 'what is going on, party
people?');
// this message will NOT go to the client defined above
io.sockets.in('foobar').emit('message', 'anyone in this room yet?');
Client side
// set-up a connection between the client and the server
var socket = io.connect();
// let's assume that the client page, once rendered, knows what room
it wants to join
var room = "abc123";
socket.on('connect', function() {
// Connected, let's sign-up for to receive messages for this room
socket.emit('room', room);
});
socket.on('message', function(data) {
console.log('Incoming message:', data);
});
Imagine a user with multiple Chat Room to choose. When he click on a specific room he will get the information of it : in this example ChatRoom1.
The client socket (belonging to the user who has click on this room) has first to join this room
→ so that's why we have :
socket.emit(room, ChatRoom1)
// on the other part the server side will add the socket id of this client to this room :
socket.on('room', function(room) {
socket.join(room);
});
Now if you want to emit a message to all socket belonging to a specific room you use this command on the server part:
io.sockets.in(ChatRoom1).emit('message', 'what is going on, party
people?');
→ in fact this command just send a message to all socket who is belonging to ChatRoom1
→ Basically a Room is just an array of socketId
SO now on the client side you have this :
socket.on('message', function(data) {
console.log('Incoming message:', data);
});
this is just a listener, and you will get in console log :
Incoming message: what is going on, party people?
As you soon you enter in a chatRoom your socket join a room and will listen for each event until you ask the socket to leave the room
So now you can imagine that in your message you have your Id , Your Room ID and your content, when you send it the server will know where to send it.
Example:
message: {
content: 'blabla',
user: me,
date: now,
RoomId: ChatRoom1
}
On the client side each time a user send a message:
socket.emit('sendMessage', message)
On the server side:
socket.on('sendMessage', function(message){
io.sockets.in(message.RoomId).emit('message', message);
})

Socket.io, message to yourself

Socket.io doesn't display messages send on yourself ip.
For example
var id = 333;
socket.broadcast.to(id).emit('user', user);
It working good, but message is only in client #333, but user than sent message, do not have a copy in the message client.
I wanted to solve in this way, but it does not work
socket.broadcast.to(socket.id).emit('user', user);
Why?
Without more code its hard to say what you want but one thing is certain in order to send a message to a single user you must use that socket object and use socket.emit
As far as i know broadcast is only used to tell everyone except for yourself.
What i usually do when it comes to keeping track of users is i have the following:
var userList = [];
io.on('connection', function (socket) {
socket.on('userData', function (userDetails) {
userDetails.socket = socket;
userList[userDetails.id] = userDetails
});
});
Basicly when a user connects to my socket and the page for the user is fully loaded it sends its id (or a token if you wish) i then map the user's socket into the list so i can quickly pick it up again if i wish to send to that user.
An example could be:
user.id = 33 connects to our server
Once loaded the users emits to our server userData function
The socket is then taken and put into the list at row 33
When we need to we can this use the following code to get the users socket:
socket = userList[33];
or if we have the object:
socket = userList[user.id];
I hope this helps you.
For this, you can use socket.emit('message').
socket.emit: Emit for only one socket.
Hope this will help you. You can also check out this link: socket.io send packet to sender only

Node.js HTTP and TCP Clients Connection

I am trying to create a system where I have a desktop client created in VB, and a browser based client, that can send messages to each other. I am using a Node.js server to handle the connections and messages.
This is the code of my Node.js server:
net = require('net')
// Supports multiple client chat application
// Keep a pool of sockets ready for everyone
// Avoid dead sockets by responding to the 'end' event
var sockets = [];
// Create a TCP socket listener
var s = net.Server(function (socket) {
// Add the new client socket connection to the array of
// sockets
sockets.push(socket);
// 'data' is an event that means that a message was just sent by the
// client application
socket.on('data', function (msg_sent) {
// Loop through all of our sockets and send the data
for (var i = 0; i < sockets.length; i++) {
// Don't send the data back to the original sender
if (sockets[i] == socket) // don't send the message to yourself
continue;
// Write the msg sent by chat client
sockets[i].write(msg_sent);
}
});
// Use splice to get rid of the socket that is ending.
// The 'end' event means tcp client has disconnected.
socket.on('end', function () {
var i = sockets.indexOf(socket);
sockets.splice(i, 1);
});
});
s.listen(8000);
console.log('System waiting at http://localhost:8000');
With this sever, I am able to send messages between two desktop clients successfully.
However, because I am using net and not HTTP I cannot get the browser based client to connect.
How can I get both the clients to connect? I would really appreciate any help/suggestions/directions. I have been searching everywhere for about 4 days now! TIA!
You could use http or express for browser based client. could check socket.io also which works on http port.
I would try to help more if know type of the desktop client you are using.

Sending to Subset of Users in Room/Channel with Socket.IO

I'm building a web application with Node (Express) and Socket.IO that has chat functionality. Because opening a new tab on a page establishes a new socket connection, I need to group all instances of a single user into their own room based on the Express session ID to enable all messages aimed at said user to appear in all duplicate tabs. This is in addition to any other room/channel they might already be logged into. At a minimum, users are subscribed to two chatrooms: the actual "real" room, and their own channel using the sessionID.
The problem is that all of the sockets for my sessionID are also in the more general room (and need to be to get messages from other users). When I send out the general chat message I'd like to omit any sockets corresponding to the sending user, as they have already received the message through their own channel. I've gone ahead and made a hash of arrays containing lists of socketIDs for that session, keyed on the sessionID. I've seen a few different syntaxes for specifying exception lists, but none seem to work for me.
The relevant code, with certain parts omitted for brevity:
var sessionSockets = {};
io.sockets.on('connection', function(socket){
if(!io.sockets.manager.rooms["/" + sessionID]) {
sessionSockets[sessionID] = [];
//send message indicating log on to all sockets except for my session
}
socket.join(sessionID); //create private channel for all sockets of the same sessionID
sessionSockets[sessionID].push(socket.id);
socket.on('chat', function(data){
var payload = {
message: data.msg,
from: data.user
};
//send back as personal message to all sockets for this session
io.sockets.in(sessionID).emit('me',payload);
//send to everyone else as regular message; WHAT SYNTAX?
io.sockets.in('').except(sessionSockets[sessionID]).emit('chat', payload);
}
}
tl;dr: How can I send a message to a subset of users in a channel/room without manually doing a comparison of arrays?
use socket.join('room') and then emit to the room by using socket.in(socket.room).broadcast.emit.
This is how you can group clients in a room and emit a perticular example to room

Categories

Resources