Node client receiving too many hit from node server on single update - node.js

I am new with the node js.
I am using node js with express.
I am create connection on server side via below code.
io.sockets.on('connection', function (socket) {
// console.log('A new socket connected with id : '+socket.id);
socket.on('error',function(e){
// console.log(e);
})
socket.on('disconnect',function(e){
// console.log( " \n disconnect \n ",e);
})
socket.on('UserRoom', function(data){
var user_id = data.user_id;
if(socket.adapter.rooms[user_id]===undefined)
{
console.log('Hey i am connected to server for User id => '+user_id);
socket.join(user_id);
}
else
{
console.log('Hey i am already connected to User id');
}
});
socket.on('JoinDraft', function(data)
{
var game_unique_id = data.game_unique_id;
socket.join(game_unique_id);
});
});
app.post('/game_update', function(req, res)
{
var target = true;
var response = '';
req.on('data', function (data) {
response += data;
});
req.on('end', function () {
res.sendStatus(200);
var result = JSON.parse(response);
game_update(result);
});
});
function game_update( result )
{
var game_unique_id = result ;
io.to(game_unique_id).emit('game_update', {"game_unique_id": game_unique_id});
};
client side code :- for joining room
function joinDraft_socket() {
// console.log(gameObj);
socket.emit('JoinDraft',{"game_unique_id" : gameObj.game_unique_id});
}
for getting node response , we have
socket.on('game_update', function(data) {
if(data.game_unique_id == gameObj.game_unique_id) {
console.log('Trigger to update ', data);
isYourPick();
}
});
Server node emit data single time to any room ( game_unique_id) then clients are receiving server ping multiple times.
Please let me know if any one face this kind of issue and how they resolved it.
Below is image of console after single update of server node , client receive multiple hits
Any help is appreciate ...
Thanks in Advance

Related

How to Emit data from function using Socket io

I am very beginner in NodeJS, I am taking data from S71200 PLC device using nodes7 library, I want to pass data using socket io emit but I can't pass data to socket io emit below my code
app.js
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var nodes7 = require('nodes7'); // This is the package name, if the repository is cloned you may need to require 'nodeS7' with uppercase S
var conn = new nodes7;
var doneReading = false;
var doneWriting = false;
var variables = {
TEST7: 'DB1,INT2.3',
TEST1: 'DB1,X0.0.3',
TEST2: 'DB1,INT2'
};
conn.initiateConnection({port: 102, host: '127.0.0.1', rack: 0, slot: 1}, connected);
function connected(err) {
if (typeof(err) !== "undefined") {
// We have an error. Maybe the PLC is not reachable.
console.log(err);
process.exit();
}
conn.setTranslationCB(function(tag) {return variables[tag];}); // This sets the "translation" to allow us to work with object names
conn.addItems(['TEST7','TEST1']);
//conn.writeItems('TEST2', 90, valuesWritten);
setInterval(function(){
conn.readAllItems(valuesReady);
},1000)
}
function valuesReady(anythingBad, values) {
if (anythingBad) { console.log("SOMETHING WENT WRONG READING VALUES!!!!"); }
console.log(values.TEST1[0],values.TEST1[1],values.TEST1[2],values.TEST7[0],values.TEST7[1],values.TEST7[2]);
//console.log( typeof(temp));
doneReading = true;
}
function valuesWritten(anythingBad) {
if (anythingBad) { console.log("SOMETHING WENT WRONG WRITING VALUES!!!!"); }
console.log("Done writing.");
doneWriting = true;
}
io.on('connection',function(socket){
console.log('one user connected '+socket.id);
socket.emit("channelname", {
message: "Passing S71200 data"
});
socket.on('disconnect',function(){
console.log('one user disconnected '+socket.id);
});
})
http.listen(3000,function(){
console.log('server listening on port 3000');
})
I am using interval function because every second data fetch from PLC device, I got all data from values.TEST1[0],values.TEST1[1],values.TEST1[2],values.TEST7[0],values.TEST7[1],values.TEST7[2] this data passing to
io.on('connection',function(socket){
console.log('one user connected '+socket.id);
socket.emit("channelname", {
message: "Passing S71200 data"
});
socket.on('disconnect',function(){
console.log('one user disconnected '+socket.id);
});
})
Help me to solve this problem

How to send message to specific user using socket_io_client flutter package

I am trying to build an chat apps using socket.io and node.js for backend and flutter for frontend... so far I have been trying to send message to all connected user, is there a way to send message to specific user? here is part of my backend code
io.on('connection', (socket) => {
console.log(`id: ${socket.id}`)
socket.on('send_message', (msg) => {
var detail = JSON.parse(msg)
socket.in(detail["receiver"]).emit('to_user', msg)
})
});
in flutter I am using socket_io_client package (https://pub.flutter-io.cn/packages/socket_io_client) but I don't know how to emit message for specific user
here is part of code for frontend
StreamController<String> _data = StreamController<String>();
socket.on('send_message', (x) {
_data.sink.add(x);
});
sendChat(String msg, String sender, String receiver) {
Map map = {"msg": msg, "snd": sender, "rcv": receiver};
var mapbody = json.encode(map);
socket.emit('send_message', mapbody);
}
Stream<String> get sendChat => _data.stream;
you have to have the socket.id and use io.sockets.socket(SocketId).emit(msg) to send message
var express = require("express");
var redis = require("redis");
var sio = require("socket.io");
var client = redis.createClient()
var app = express.createServer();
var io = sio.listen(app);
io.set("store", new sio.RedisStore);
// In this example we have one master client socket
// that receives messages from others.
io.sockets.on('connection', function(socket) {
// Promote this socket as master
socket.on("I'm the master", function() {
// Save the socket id to Redis so that all processes can access it.
client.set("mastersocket", socket.id, function(err) {
if (err) throw err;
console.log("Master socket is now" + socket.id);
});
});
socket.on("message to master", function(msg) {
// Fetch the socket id from Redis
client.get("mastersocket", function(err, socketId) {
if (err) throw err;
io.sockets.socket(socketId).emit(msg);
});
});
});
some options you have here.
first :
you can store your connected clients ids to redis .
use io-redis :
and store your client id in it:
for storing ids in redis:
await redisClient.lpush(`socket_members`, socket.id);
for getting the specefic id:
let client = await redisClient.lrange(
`socket_members`,
0,
socket.id
);
the second option is you can create an authentication middleware
const jwt = async(socket, next) => {
let token = socket.handshake.query.token
let verify = jwt.verify(socket.handshake.query.token, jwt_encryption, async(err, decoded) => {
// find user with decoded token
if (!user) {
return next(new Error(JSON.stringify({ status: 401, message: 'unuthorized' })));
}
socket.user = user._doc
return next()
})
};
and use it in socket io instance :
io.use(jwt);
the authenticated user is in socket.user.
hope this would help

NodeJS Net.createServer

Hey uh I am having an issue and I think this is probably related to net.createserver.
The issue is that whenever the first client joins after that another second client joins, the first client can control the second client and then the first client disconnects because the socket(end) event gets triggered. Is it related to sockets or something or the server can't handle two connections? Please help
The code:
handleGame: function() {
console.log(log.success('The source is starting!'));
var server = net.createServer(function(socket) {
console.log('A client has connected' + "\r\n");
socket.setEncoding('utf8')
global.clientObjz = new client(socket);
game.addClient(clientObjz);
socket.on('data', function(data) {
data = data.toString().split('\0')[0];
console.log('Incoming data: ' + data + "\r\n")
if (data == "<msg t='sys'><body action='verChk' r='0'><ver v='153' /></body></msg>" | data == "<msg t='sys'><body action='rndK' r='-1'></body></msg>" | data.startsWith("<msg t='sys'><body action='login' r='0'>")) {
parseXml(data, function(err, result) {
var type = result.msg['$'].t,
action = result.msg.body[0]['$'].action;
var method = Game.xmlHandlers[type][action];
if (typeof Game[method] == 'function') {
Game[method](data, client);
}
});
}
var dataType = data.charAt(0);
if (dataType == '%') {
game.handleraw(data, clientObjz);
}
});
socket.on('end', function() {
game.removeClient(socket);
console.log('A client has disconnected');
});
socket.on('error', function(err) {
console.log(err);
});
});
server.listen(Game1, "localhost", function() {
console.log('Server is listening on port 6113');
});
}
//this code is another file as i am calling it by game.clients.push
addClient: function(client) {
if (client) {
self.clients.push(client);
}
}
Yes, it's a clubpenguin emulator
full code: https://github.com/dev3211/bingojs
You need to implement socket channels if you are doing this only with NodeJS net.createServer. If you want it simple, you could look for something using express.js, something like this: https://medium.com/factory-mind/websocket-node-js-express-step-by-step-using-typescript-725114ad5fe4

Make a new prop in socket io object and get undefined using react.js as client

I was trying to store data into a socket prop that I can reference it later. However, on others socket.on it comes out as undefined
Here is the code:
var userlist = ['Dang Huy','Alice','Bui Sam', 'Hai Hai'];
var onlineUser = [];
io.on('connection', socket => {
socket.on('userOnline', (data) => { //User Alice go in
if(userlist.includes(data)){
onlineUser.push(data);
io.sockets.emit('onlineUser', onlineUser);
}
socket.user_name = data; // store data into user_name
console.log(socket.user_name + ' is online'); //logout Alice is online
})
socket.on('userSendMessage', (data) => {
console.log(socket.user_name) // socket.user_name is undefined here!!
console.log(data) // still log out the message from the client side
io.sockets.emit('serverSendMessage', 'Hello')
})
socket.on('disconnect', function(){
onlineUser.splice(onlineUser.indexOf(socket.user_name), 1)
io.sockets.emit('onlineUser', onlineUser)
})
})
What do you mean by next event (could you provides an example?)Oh I notice something very wrong , you won't never go to some event and that is purely normal, your socket scope variable is into {} & you ask it out of them, just move the listeners up:
var userlist = ['Dang Huy','Alice','Bui Sam', 'Hai Hai'];
var onlineUser = [];
io.on('connection', socket => {
socket.on('userOnline', (data) => { //User Alice go in
if(userlist.includes(data)){
onlineUser.push(data);
io.sockets.emit('onlineUser', onlineUser);
}
socket.user_name = data; // store data into user_name
console.log(socket.user_name + ' is online'); //logout Alice is online
})
socket.on('userSendMessage', (data) => {
console.log(socket.user_name) // socket.user_name is undefined here!!
console.log(data) // still log out the message from the client side
io.sockets.emit('serverSendMessage', 'Hello')
})
socket.on('disconnect', function(){
onlineUser.splice(onlineUser.indexOf(socket.user_name), 1)
io.sockets.emit('onlineUser', onlineUser)
})
})
I found it out myself. The Problem was: I was using Reactjs as front-end framework, so each component has different socket session, therefore socket.username is defined if I call socket.emit('userSendMessage') in that same component that I connected to. If I socket.emit('userSendMessage') in other component, It will return undefined because of different session of each component.

The socket.io is emitting to all rooms instead of the specified ones

I'm new to node and socket io. I'm trying to implement a realtime notification system for couple of my own apps. So, using node, express and socket io, the code is given below:
Server Side Code:
io.on('connection', function (socket) {
socket.on('subscribe', function(room) {
socket.join(room);
});
socket.on('unsubscribe', function(room) {
socket.leave(room);
});
});
Client Side Code:
var sio = io.connect('http://localhost:9000');
var ch1 = sio.emit('subscribe', 'channel1');
ch1.on('log', function (data) {
console.log('channel1: ', data);
});
var ch2 = sio.emit('subscribe', 'channel2');
ch2.on('log', function (data) {
console.log('channel2: ', data);
});
I'm firing/emitting the event from a route (express) for example:
app.get('/', function(req, res) {
var data1 = {
channel: 'channel1',
evennt: 'log',
message: 'Hello from channel1...'
};
io.to(data1.channel).emit(data1.event, data1);
});
When I'm hitting the route, the io.to(data1.channel).emit(data1.event, data1); is working but it sending the data to both rooms/channels but I was expecting to get the data only in ch1 because data1.channel contains channel1 so I was expecting the following handler will receive the data:
ch1.on('log', function (data) {
console.log('channel1: ', data);
});
Notice that, both channels have same log event. Am I on the right track. Is it possible at all?
var ch1 = sio.emit('subscribe', 'channel1');
var ch2 = sio.emit('subscribe', 'channel2');
You're subscribing the same socket (sio) to both rooms. Also, ch1 and ch2 are references to sio.
If you want to test it properly, you should create a second socket for the second channel:
var sio2 = io.connect('http://localhost:9000');
var ch2 = sio2.emit('subscribe', 'channel2');

Resources