Sending Data to Target Client with socket.io - javascript

For example, in the client side, i have two registred and online user.
UID 1 : Leon
UID 2 : Albert
Leon wants to know how much have credit.
for example, Leon hit the button to get credit, so:
socket.emit('my_credit', 1);
And in the server side, i use this code:
Example:
var express = require('express');
var server = express();
var app = require('http').createServer(server);
var io = module.exports.io = require('socket.io')(app);
io.on('connection', function(socket){
socket.on('my_credit', function(uid){
getUserCredit(uid, (result) => {
socket.emit('my_credit', result);
})
});
});
Now, in the client side, all users receive this value!
If I want only Leon to receive this value, how can i do ?
How can i do in the server side to find currect id ?

For sending message to target client, use to function:
Eg:
io.sockets.to(/* Unique ID */).emit('message');
Or:
io.on('connection', function (socket) {
socket.on('check', function(){
io.sockets.to(socket.id).emit('check', 'Just You: ' + socket.id);
});
});

Yo!
So basically, at the moment, I dont know any other solutions than checking socket id.
Example to emit client side:
socket.emit('my_credit', {user: 1, id: socket.id});
Receiving server side :
var express = require('express');
var server = express();
var app = require('http').createServer(server);
var io = module.exports.io = require('socket.io')(app);
io.on('connection', function(socket){
socket.on('my_credit', function(uid){
getUserCredit(uid.user, function(result){
socket.emit('my_credit', {res: result, id: uid.id});
})
});
});
And receiving client side :
socket.on('my_credit', (message) => {
if (message.id !== socket.id) return;
// your code here
})

Related

Socket.io client doesn't receive message from Server

I'm using Socket.IO for websockets and I want clients receive a welcome message in console from server when they connect but it's not working:
Server:
var fs = require('fs');
var https = require('https');
var express = require('express');
var app = express();
var options = {
key:
fs.readFileSync('/myfolder/mykey.pem'),
cert:
fs.readFileSync('/myfolder/mychain.pem')
};
var serverPort = 3080;
var server = https.createServer(options,app);
var io = require('socket.io')(server);
app.get('/',function(req,res){
res.sendFile(__dirname+'/index.html');
});
server.listen(serverPort, function(){
console.log('Server is working');
//console.log(__dirname);
});
io.on('connection', function(socket){
console.log("Connected!");
socket.broadcast.emit("Welcome","Good day sunshine!");
});
Client:
<script src="https://localhost:3080/socket.io/socket.io.js"></script>
<script>
var URL_SERVER = 'https://localhost:3080';
var socket = io.connect(URL_SERVER);
socket.on("Welcome", function(data){
console.log(data);
});
</script>
I'm getting message console in server side but not the server answer in the console client.
How can I fix it?
To broadcast, simply add a broadcast flag to emit and send method
calls. Broadcasting means sending a message to everyone else except
for the socket that starts it.
Reference : https://socket.io/docs/

Node.js socket.io returning multiple values for a single event

I'm trying to build a simple app using Node, Express (^4.15.3), and socket.io (^2.0.3). I'm building a simple chat app, however each time I add a new message, I get an additional response each time.
For example, if the first message was "Hello", I would be returned:
Hello
If I then add a subsequent message of "Is anyone there?", I get back:
Is anyone there?
Is anyone there?
And so on...each time I get an additional response back.
Here's my code - it feels like it's something really obvious and I may have been staring at it too long...
//app.js
var express = require("express");
var bodyParser = require("body-parser");
var expressValidator = require('express-validator');
var session = require('express-session');
var passport = require("passport");
var app = express();
var http = require('http');
var server = http.createServer(app);
var io = require('socket.io').listen(server);
app.use(express.static("public"));
app.set("view engine", "ejs");
server.listen(process.env.PORT || 3000, process.env.IP, function(){
console.log("Server starting...");
});
app.get('/testsocket', function(req, res){
res.render('sockets/test');
});
io.sockets.on('connection', function(socket){
console.log('Connected')
socket.on('send message', function(data){
console.log('Got the message...');
io.sockets.emit('new message', data)
});
});
And then client side
//client side
$(function() {
var socket = io.connect();
var $messageForm = $('#send-message');
var $messageBox = $('#message');
var $chat = $('#chat');
$messageForm.submit(function(e){
e.preventDefault();
socket.emit('send message', $messageBox.val());
$messageBox.val('');
socket.on('new message', function(data){
$chat.append(data + "<br>");
});
});
});
I think the problem is that you're registering the listener for new message inside your submit function. So each time you submit the form you register a new listener, in addition to any previous listeners. Try putting the socket.on('new message', ... section outside the submit handler.

io.on is not a function

I have this code working for receiving data from my Arduino but I will like to send data back to my Arduino and get a response on my client page. I added a listening function but I keep getting io.on is not a function when I send data from my client page.
test.js
io.listen(app.listen(3000)).on('connection', function (client) {
// store client into array
clients.push(client);
// on disconnect
client.on('disconnect', function() {
// remove client from array
clients.splice(clients.indexOf(client), 1);
});
// I added this to listen for event from my chart.JS
io.on('connection', function(socket){
socket.on('LED on', function (data) {
console.log(data);
});
socket.on('LED off', function (data) {
console.log(data);
});
});
});
Your value of io is not what it should be.
The usual way of doing things is like this:
var app = require('http').createServer(handler)
var io = require('socket.io')(app);
var fs = require('fs');
app.listen(80);
io.on('connect', ...);
But I'm guessing that your value of io is something like this:
var io = require('socket.io');
That's not the same thing. That's the module handle. But, when you do it this way:
var io = require('socket.io')(app);
Then, io is a socket.io instance. You can bind listeners to an instance, not to the module handle.
In every single socket.io server-side example on this doc page, they use one of these forms:
var io = require('socket.io')(app);
var io = require('socket.io')(port);
var io = require('socket.io')(server);
with this:
io.on('connection', ....);
Nowhere do they do:
var io = require('socket.io`);
io.listen(server);
io.on('connection', ....);
That's just the wrong value for io.
Long story, shortened, you need to fix what you assign to io to be consistent with the docs. It's the return value from require('socket.io')(app); that gives you a socket.io instance object that you can then set up event handlers on.
if you are using express
var express = require('express');
var app = express();
var server = require('http').Server(app);
var io = require('socket.io')(server);
let APP_PORT=3000;
server.listen(APP_PORT,()=>{
console.log(`SERVER RUNNING ON PORT : ${APP_PORT}`);
});
io.on('connection', (socket) => {
/* SOCKET - CORE EVENTS */
socket.on('connect', (message) => {
console.log("connected: " + message+"socket_id:"+socket.id);
});
socket.on('disconnect',(data)=>{
console.log('user disconnected:' + socket.id);
});
socket.on('error', function (err){
console.log('received error from client:', socket.id,' Error :',err);
});
});

How to push notification to specific user Node + AngularJS + Laravel

I need help how to push notification to specific user. I can now push notifcation but all user will get that notification. I can filter it on clinet side but I think it is unsecure...
First I send data with laravel 5:
$redis = Redis::connection();
$redis->publish('update.answer', json_encode($events));
here is my node.js i emite data:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var Redis = require('ioredis');
var redis = new Redis();
redis.subscribe('update.group', function(err, count) {
});
redis.subscribe('update.question', function(err, count) {
});
redis.subscribe('update.answer', function(err, count) {
});
redis.subscribe('update.comment', function(err, count) {
});
redis.on('message', function(channel, message) {
message = JSON.parse(message);
console.log(message);
io.emit(channel, message);
});
http.listen(3000, function(){
console.log('Listening on Port 3000');
});
and with angularjs I take data and push to the client.
socket.on('update.answer',function(data){
if($scope.remove){
$scope.remove = false;
}
$scope.feed = $("#feed").val();
if(parseInt($scope.feed) === parseInt(data.userID)){
$scope.answers.push(data);
$scope.$digest();
}
});
WIth this part:
$scope.feed = $("#feed").val();
if(parseInt($scope.feed) === parseInt(data.user_id) && data.admin_id !== null){
}
I check if client should get notification but it is unsecure...
Any way to improve this?
To push message to specific user , you must store his/her reference somewhere.
for ex
io.on('connection', function(socket) {
socket.on('add-user', function(data){
clients[data.username] = socket;
});
});
now to push message to specific user just use his username to retrive his socket
clients[data.username].emit(channel, message);
Update : Explanation
This Assume that each user who uses you web app is having some sort of authentication.
As soon as user login into your application , let him join on the nodejs backend socket.
on client side
socket.emit('add-user',userObj);
});
userObj is object that contains user details,you can send the username alone too
socket.emit('add-user',username);
in your nodejs first decalre one array that contains the socket of all the users who joins the website
var clients = [];
now in your nodejs application write this additional code
io.on('connection', function(socket) {
socket.on('add-user', function(data){
clients[data.username] = socket;
});
});
up to this moment the user who login into your website will call add-user event from client side which will in turn call add-user on nodejs and there socket will be added into the clients array
now to send message to any particular user you must know there username,so if you know the username of the user then you can simply emit message to them using
clients[data.username].emit(channel, message);

how to get session id of socket.io client in Client

I want to get session id of client in my socket.io client.
here is my socket.io client :
var socket = new io.Socket(config.host, {port: config.port, rememberTransport: false});
// when connected, clear out display
socket.on('connect',function() {
console.log('dummy user connected');
});
socket.on('disconnect',function() {
console.log('disconnected');
});
socket.connect();
return socket;
I want to get session id of this client , how can i get that ?
Have a look at my primer on exactly this topic.
UPDATE:
var sio = require('socket.io'),
app = require('express').createServer();
app.listen(8080);
sio = sio.listen(app);
sio.on('connection', function (client) {
console.log('client connected');
// send the clients id to the client itself.
client.send(client.id);
client.on('disconnect', function () {
console.log('client disconnected');
});
});
On socket.io >=1.0, after the connect event has triggered:
var socket = io('localhost');
var id = socket.io.engine.id
I just had the same problem/question and solved it like this (only client code):
var io = io.connect('localhost');
io.on('connect', function () {
console.log(this.socket.sessionid);
});
* Please Note: as of v0.9 the set and get API has been deprecated *
The following code should only be used for version socket.io < 0.9
See: http://socket.io/docs/migrating-from-0-9/
It can be done through the handshake/authorization mechanism.
var cookie = require('cookie');
io.set('authorization', function (data, accept) {
// check if there's a cookie header
if (data.headers.cookie) {
// if there is, parse the cookie
data.cookie = cookie.parse(data.headers.cookie);
// note that you will need to use the same key to grad the
// session id, as you specified in the Express setup.
data.sessionID = data.cookie['express.sid'];
} else {
// if there isn't, turn down the connection with a message
// and leave the function.
return accept('No cookie transmitted.', false);
}
// accept the incoming connection
accept(null, true);
});
All the attributes, that are assigned to the data object are now accessible through the handshake attribute of the socket.io connection object.
io.sockets.on('connection', function (socket) {
console.log('sessionID ' + socket.handshake.sessionID);
});
On Server side
io.on('connection', socket => {
console.log(socket.id)
})
On Client side
import io from 'socket.io-client';
socket = io.connect('http://localhost:5000');
socket.on('connect', () => {
console.log(socket.id, socket.io.engine.id, socket.json.id)
})
If socket.id, doesn't work, make sure you call it in on('connect') or after the connection.
For some reason
socket.on('connect', function() {
console.log(socket.io.engine.id);
});
did not work for me. However
socket.on('connect', function() {
console.log(io().id);
});
did work for me. Hopefully this is helpful for people who also had issues with getting the id. I use Socket IO >= 1.0, by the way.
Try from your code
socket.socket.sessionid
ie.
var socket = io.connect('http://localhost');
alert(socket.socket.sessionid);
var sendBtn= document.getElementById('btnSend');
sendBtn.onclick= function(){
var userId=document.getElementById('txt1').value;
var userMsg = document.getElementById('txt2').value;
socket.emit('sendto',{username: userId, message: userMsg});
};
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
socket.on('message',function(data){ console.log(data);});
Try this way.
var socket = io.connect('http://...');
console.log(socket.Socket.sessionid);

Categories