Socket.io send data only a client who make request - node.js

I'm sending data to all clients but I need to send the data only one client (who make request) too.
app.post(.....){
myModel.save(function (err) {
if (err) return handleError(err);
///send to all
io.sockets.emit("ev", { ...... });
//// send to one client
......
});
}
There is a function called io.sockets.emit but there is no io.socket.emit.

I assume that in the post method you have identified the user or session.
So you can create a room per user to later emit on it.
client.js
var room = "#usernameRoom";
socket.on('connect', function() {
socket.emit('privateroom', room);
});
socket.on('privatemessage', function(data) {
console.log('Incoming private message:', data);
});
server.js
io.sockets.on('connection', function(socket) {
var socket_room;
socket.on('privateroom', function(room) {
socket_room = room;
socket.join(room);
});
socket.on('disconnect', function() {
if (socket_room) {
socket.leave(socket_room);
}
});
});
app.post(.....){
myModel.save(function (err) {
if (err) return handleError(err);
///send to all
io.sockets.emit("ev", { ...... });
//// send to one client
// now, it's easy to send a message to just the clients in a given private room
privateRoom = "#usernameRoom";
io.sockets.in(privateRoom ).emit('privatemessage', 'Never reveal your identity!');
});
}
hope that helps

Related

Connection socket.io incremented after stopping the server

I have a problem with socket.io from nodeJs.
I am trying to create a connection from a client to a server. Once the client is connected, the server sends a message to the client (ack).
Until then, everything works fine but when I disconnect the server and restart it, it sends me the message twice to the client.
If I repeat the manipulation a third time, three messages will appear.
I have captured the problem:
client.js
var socket = require('socket.io-client')('http://localhost:8050', {
'forceNew':true
});
socket.on('connect', onConnect);
function onConnect(){
console.log('connect ' + socket.id);
socket.emit('sendConnect','First connect');
socket.on("ack", function(data) {
console.log("ack reçu");
});
socket.on('disconnect', function(reason) {
console.log(reason);
});
}
server.js
var io = require("socket.io");
var sockets = io.listen(8050);
sockets.on('connection', function (socket) {
socket.on('sendConnect', function (data) {
console.log("message :" + data);
socket.emit('ack');
socket.on('disconnect', function() {
console.log('Got disconnect!');
});
});
});
I looked if this bug was already arriving without finding an answer.
I must surely be doing something wrong!
Thank you in advance for your help.
Your onConnect function adds new event listeners each time the socket connects. Move the event subscriptions out of onConnect like this:
var socket = require('socket.io-client')('http://localhost:8050', {
forceNew: true
});
socket.on('connect', onConnect);
socket.on('ack', function(data) {
console.log('ack reçu');
});
socket.on('disconnect', function(reason) {
console.log(reason);
});
function onConnect() {
console.log('connect ' + socket.id);
socket.emit('sendConnect', 'First connect');
}

io.to('socketId') not emitting the event

I want to send message to specific socket . I have saved the socketId in mongoo db . when i emit the event its not emitting the event . its works fine if i emit without specific socket what could be the issue ./ please help me
here is my code
io.on('connection', function (socket) {
socket.on('save-message-private',function(data){
console.log('private messgae ')
OnlineUsers.find({username:data.receiver},function(err,res){
if(!err){
// console.log(res)
console.log(res[0].socketId)
io.to(res[0].socketId).emit('new-message-private', { message: res });
}
else
console.log(err)
})
})
});
And here is my front end in angular 4
ngOnInit() {
var user = JSON.parse(localStorage.getItem("user"));
console.log(user)
if(user!==null) {
this.socket=io('http://localhost:4000',{query:"username="+user.nickname});
this.getChatByRoom(user.room);
this.msgData = { room: user.room, nickname: user.nickname, message: '',receiver:'group' }
this.joinned = true;
this.scrollToBottom();
this.getOnlineUsers();
this.socket.on('new-message', function (data) {
if(data.message.room === JSON.parse(localStorage.getItem("user")).room) {
this.chats.push(data.message);
this.msgData = { room: user.room, nickname: user.nickname, message: '' }
this.scrollToBottom();
}
}.bind(this));
this.socket.on('new-message-private',function(data){
console.log('private new')
console.log(data);
}.bind(this));
}
}
new-private-message not working
My socketId saved in db was different from client side socketId . so I updated the socketId on db and problem solved

Send update notification to particular users using socket.io

Following is the code on front end, where storeSelUserId contains user_id to send the message-
FYI - Node Version 1.1.0
// Socket Notification
var socket = io('http://localhost:6868');
socket.on('connection', function (data) {
socket.emit('send notification', { sent_to: storeSelUserId });
});
Following is the server code in routes file -
var clients = {};
io.on('connection', function (socket) {
socket.emit('connection', "Connection Created.");
socket.on('send notification', function (sent_to) {
console.log(sent_to);
});
});
In console sent_to is showing the array of user_id.
Now being a starter in socket.io I stuck with the solution that how do I send the message to these particular userids.
I search and found that I need to push each user with its sockets so I reformed it to -
var users = [];
io.on('connection', function (socket) {
users.push({socket_id: socket.id});
socket.emit('connection', "Connection Created.");
socket.on('send notification', function (sent_to) {
console.log(sent_to);
});
});
But I am in dilemma that else do I need to do to store which user_id refers to which socket_id and then update the div of users with that particular ids?
EDIT -
Add Controller - (Front End)
Front end Interface where memo is created and send to particular users
var socket = io('http://localhost:6868');
socket.on('connection', function (data) {
socket.emit('send memo notification', {creator_id: creator_id, sent_to: [Array of user_ids to whom memo to send]});
});
Dashboard controller - (Front End)
Front end Interface where notification count to show "notificationCount"
if (SessionService.currentUser._id) {
var socket = io('http://localhost:6868');
socket.on('connection', function (data) {
socket.emit('get notifications', {user_id: SessionService.currentUser._id});
});
socket.on('notification data', function(data){
console.log("-- Not Data Test -");
$scope.notificationCount = data.length;
});
}
Code at server end -
io.on('connection', function (socket) {
socket.emit('connection', "Connection Created.");
socket.on('send memo notification', function(data) {
notifications.createNotification(data);
});
socket.on('get notifications', function(data){
notifications.getNotifications(data, function(response){
socket.emit('notification data', response.data);
});
});
});
Backend controller code -
exports.getNotifications = function(data, callback) {
var userId = data.user_id;
Notification.find({receiver_id: userId}, function(err, response){
if (err)
callback({"message": "error", "data": err, "status_code": "500"});
else
callback({"message": "success", "data": response, "status_code": "200"});
});
};
exports.createNotification = function(data) {
var notificationData = data;
var x = 0;
for(var i=0; i< notificationData.length; i++) {
// Code
Notification(notificationData[i]).save(function(err,response){
if (err)
return false;
});
if (x === notificationData.length - 1) {
return true;
}
x++;
}
};
If you want to use your own user ids then there is no way around mapping the socket id to the user id. I assume a client knows its user id from somewhere, so it could send its user id to the server after connection.
Client
socket.on('connection', function (data) {
socket.emit('setUserId', myUserId);
});
The server saves the socket for each user id.
socket.on('setUserId', function (userId) {
users[userId]=socket;
});
If you have such a mapping in the server you can send a message just to this client using the user id.
socket.on('send notification', function (userId) {
users[userId].emit('notification', "important notification message");
});
Edit: Saving the corresponding socket directly is even better.
According to what i understand, you need private notification send to only some users. For that, save your users name to whom you want to send and their corresponding socket in different hashes.
username [socket.name] = username to be added;
usersocket [ socket.name ] =socket;
Then to emit the messages to that user only, use
usersocket[ socket.name ].emit('event for send message', ' what you want to send ');

node.js dynamic chat room

I am relatively new to using node.js and I have been searching for awhile but I haven't been successful in implementing socket.join
I have a chat room which I want to be setup privately between two users, similar to private messaging.
What I wish to have is make dynamic chat rooms between users. The problem I am getting right now is that the messages are still being broadcast to all the clients connected to the server.
Here's what I have on the server
server.js
io.sockets.on( 'connection', function( socket ) {
var unique_room = "";
socket.on('join', function(room) {
socket.join(room);
unique_room = room;
console.log("User Joined the room: "+room);
});
socket.on('message', function (data) {
io.sockets.in(unique_room).emit('message', data.message);
});
});
server.listen(1337);
client.js
var socket = io.connect( 'http://localhost:1337' );
socket.on('connect', function() {
socket.emit('join', 'dddsdjkfh1123'); //chat room id unique to two users
});
socket.on( 'message', function( data ) {
$("#chat" ).html(data.user + ":" + data.message);
});
//Form js
function sendpm(room,message,name) {
socket.emit( 'message', { room: room, message: message, name: name });
}
Please let me know what I am doing wrong. Any help would be greatly appreciated.
Thank you so much.
You should emit some the room id from the client when you send the message, and get that room id to send message to only that client in that room.
Try doing this in your server.js:
io.sockets.on( 'connection', function( socket ) {
socket.on('join', function(room) {
socket.join(room);
socket.room = room;
console.log("User Joined the room: "+socket.room);
});
socket.on('message', function (data) {
io.sockets.in(data.room).emit('message', data.message);
});
});

POST data through socket.io to app.js

I would like to:
retrieve data entered from input forms.
send the data through socket.io and send console log saying done
receive the data on express app.js
insert the data into a mongodb database using mongoose.
I understand emit messages but not sure how to post data through. thank you in advance
my app.js is set up like this:
//app.js config ...
var socket = io.listen(server);
socket.on('connection', function(socket) {
console.log('socket.io connected');
});
app.post('/go', function(req, res) {
socket.on('data', function(data) {
new Order({
routeFrom : data.routeFrom,
routeTo : data.routeTo,
leaving: data.leaving
}).save(function(err, docs) {
if(err) { console.log("error"); }
res.json(data);
});
socket.emit('callback', {done: 'Done'});
});
});
my index.ejs file:
<script src="/socket.io/socket.io.js"></script>
var socket = io.connect('http://localhost:3000');
$('#send').on('click', function() {
$.post('/go', {
socket.emit('data', {
routeFrom: $('#rf').val(),
routeTo: $('#rt').val(),
leaving: $('#l').val()
});
});
socket.on('callback', function(data) {
console.log(data);
});
});
You don't need POST at all.
I would do on the client side:
var socket = io.connect('http://localhost:3000');
$('#send').on('click', function(event) {
event.preventDefault();
socket.emit('data', {
routeFrom: $('#rf').val(),
routeTo: $('#rt').val(),
leaving: $('#l').val()
});
});
socket.on('callback', function(data) {
console.log(data.done);
// Print the data.data somewhere...
});
And on the server side:
//app.js config ...
var socket = io.listen(server);
socket.on('connection', function(socket) {
console.log('socket.io connected');
});
socket.on('data', function(data) {
new Order({
routeFrom : data.routeFrom,
routeTo : data.routeTo,
leaving: data.leaving
}).save(function(err, docs) {
if(err) { return console.log("error"); }
socket.emit('callback', {done: 'Done', data: data});
});
});

Resources