How to configure socket io and socket io client - node.js

Good day
I need to connect a lot of pc's to a main server, through a server of units
I have something but I don't have all complete
Main Server
socketIo = require("socket.io"),
ioServer = socketIo(server),
ioServer.sockets.on("connection",function(socket){
// Display a connected message
console.log("Server-Client Connected!");
// When we receive a message...
socket.on("message",function(data){
// We got a message... I dunno what we should do with this...
console.log(data);
console.log(data.from + " is connected with ip " + data.ip);
socket.emit('message', { 'from': '10.19.17.101', 'answer':'I already added you '+data.from });
});
});
Server Units
socketIo = require("socket.io"),
ioServer = socketIo(server),
ioClient = require("socket.io-client")('http://10.19.17.101:7700')
ioClient.on('connect', function(){
ioClient.on('message',function(data){
console.log(data.from + " answered: " + data.answer);
ioServer.to('pxe4').emit('message',data);
});
ioClient.emit('message',{ 'from': 'pxe4', 'ip':'10.19.16.84' });
});
ioServer.sockets.on("connection",function(socket){
// Display a connected message
console.log("User-Client Connected!");
// When we receive a message...
socket.on("message",function(data){
// We got a message... I dunno what we should do with this...
console.log(data);
console.log(data.from + " is connected with ip " + data.ip);
socket.emit('message', { 'from': '10.19.16.84', 'answer':'I already added you '+data.from });
ioClient.emit("message",data);
});
socket.on("disconnect",function(data){
// We need to notify Server 2 that the client has disconnected
ioClient.emit("message","UD,"+socket.id);
// Other logic you may or may not want
// Your other disconnect code here
});
});
Units
ioClient = require("socket.io-client")('http://10.19.16.84:7770'),
ioClient.on('connect', function(){
ioClient.on('message',function(data){
// We received a message from Server 2
// We are going to forward/broadcast that message to the "Lobby" room
console.log(data.from + " answered: " + data.answer);
});
ioClient.emit('message',forsend);
});
I was wondering if at this moment I can send some information from Main Server to a specific unit?
If someone could help me, I will be thankful.

When connecting from each client on the main server or Server Units you recive a socket object which contains socketid. You have to save those socket id's in some data storge for speedy access with the server information. When you have to emit data to specific socket you have to query that specific socket from data storage and emit the data. On disconnect you have to pull that particular socket from data storage

Related

Nodejs/express server uses one socket.id for 2 RN clients in message saving

The nodejs (10.16) and express (4.16) backend server (server) runs with socket.io 2.2.0 for a chat app. The message received on the server will be broadcast to the clients connecting to the same room (channel). The socket.io instance is created in index.js:
const io = require('socket.io')(server);
io.on('connection', async (socket) => {
socket.my_id = "";
console.log("socket.id : ", socket.id);
app.set("socket", socket);
console.log("Socketio server is initialized");
//disconnect
socket.on('disconnect', async function() {
//if (socket.my_id) helper.RemoveSocketUser(user.fort_token, socket.my_id);
console.log('disconnected event');
});
});
server.listen(port, () => {};
Then after a message is saved on the server, the socket is used to broadcast to the clients in the same room.
try {
await msg.save();
msg.user_name = req.user.name;
msg.user_avatar = req.user.user_data.avatar;
const io = req.app.get("io");
const socket = req.app.get('socket');
const room = msg.event_id.toString();
socket.my_id = req.user.id;
socket.join(room);
console.log("socket in new message : ", socket.id);
console.log("msg before broadcast : ", msg.data.msg_body);
io.to(room).emit("event message", msg);
return res.status(200).send(req.body.data.msg_body);
} catch (err) {
console.log("Error in saving/braodcasting a new message", err);
return res.status(400).send(err.message);
};
From the console output, the socket.id is the same for 2 clients connecting to the same room and chatting. Here is a output for Android emulator running on port 8081:
socket in new message : b0po9l6hGZUi9xVDAAAE
msg before broadcast : 8081
Here is another android emulator running on port 9090:
socket in new message : b0po9l6hGZUi9xVDAAAE
msg before broadcast : 9090
However the socket.id on clients side is not the same. What causes the server using the same socket.id for 2 clients?
What you are trying to do is accessing socket object stored in express,
which will update socket object every time new socket get connected that's why you are getting same socket id [ last connected ].
to access specific socket from outside the io connection scope, you have to get the socket instance from io object.
you need to store socket id somewhere in database or memory like redis.
const socketid = `get user's latest connected socket id.`
cont socket = io.sockets.sockets[socketid];
socket.emit('req', { data: "something"})

use node.js cluster with socket.io chat application

I'm trying to learn node.js cluster with socket.io to create a chat application... the problem is that I can't seem to get things working.
i've been trying to go through all the tutorials including the one that I get from this http://stackoverflow.com/questions/18310635/scaling-socket-io-to-multiple-node-js-processes-using-cluster/18650183#18650183
when I try to open two browsers, the messages does not go to the other browser.
here's the code that i got
var express = require('express'),
cluster = require('cluster'),
net = require('net'),
socketio = require('socket.io'),
socket_redis = require('socket.io-redis');
var port = 3000,
num_processes = require('os').cpus().length;
if (cluster.isMaster) {
// This stores our workers. We need to keep them to be able to reference
// them based on source IP address. It's also useful for auto-restart,
// for example.
var workers = [];
// Helper function for spawning worker at index 'i'.
var spawn = function(i) {
workers[i] = cluster.fork();
// Optional: Restart worker on exit
workers[i].on('exit', function(code, signal) {
console.log('respawning worker', i);
spawn(i);
});
};
// Spawn workers.
for (var i = 0; i < num_processes; i++) {
spawn(i);
}
// Helper function for getting a worker index based on IP address.
// This is a hot path so it should be really fast. The way it works
// is by converting the IP address to a number by removing non numeric
// characters, then compressing it to the number of slots we have.
//
// Compared against "real" hashing (from the sticky-session code) and
// "real" IP number conversion, this function is on par in terms of
// worker index distribution only much faster.
var worker_index = function(ip, len) {
var s = '';
for (var i = 0, _len = ip.length; i < _len; i++) {
if (!isNaN(ip[i])) {
s += ip[i];
}
}
return Number(s) % len;
};
// Create the outside facing server listening on our port.
var server = net.createServer({ pauseOnConnect: true }, function(connection) {
// We received a connection and need to pass it to the appropriate
// worker. Get the worker for this connection's source IP and pass
// it the connection.
var worker = workers[worker_index(connection.remoteAddress, num_processes)];
worker.send('sticky-session:connection', connection);
}).listen(port);
} else {
// Note we don't use a port here because the master listens on it for us.
var app = new express();
// Here you might use middleware, attach routes, etc.
app.use('/assets', express.static(__dirname +'/public'));
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
// Don't expose our internal server to the outside.
var server = app.listen(),
io = socketio(server);
// Tell Socket.IO to use the redis adapter. By default, the redis
// server is assumed to be on localhost:6379. You don't have to
// specify them explicitly unless you want to change them.
io.adapter(socket_redis({ host: 'localhost', port: 6379 }));
// Here you might use Socket.IO middleware for authorization etc.
io.on('connection', function(socket) {
console.log('New client connection detected on process ' + process.pid);
socket.emit('welcome', {message: 'Welcome to BlueFrog Chat Room'});
socket.on('new.message', function(message) {
socket.emit('new.message', message);
})
});
// Listen to messages sent from the master. Ignore everything else.
process.on('message', function(message, connection) {
if (message !== 'sticky-session:connection') {
return;
}
// Emulate a connection event on the server by emitting the
// event with the connection the master sent us.
server.emit('connection', connection);
connection.resume();
});
}
If I understand correctly, your problem is that the messages from a client are not broadcasted to the other clients. you can solve this easily using :
io.on('connection', function(socket) {
console.log('New client connection detected on process ' + process.pid);
socket.emit('welcome', {message: 'Welcome to BlueFrog Chat Room'});
socket.on('new.message', function(message) {
socket.emit('new.message', message); // this line sends the message back to the emitter
socket.broadcast.emit('my message', msg); // this broadcasts the message to all the clients
})
});
There are different ways to emit a message. The one you're using emits the message only to the socket that first sent a 'new.message' message to the server. Which means that a socket will receive the message that you emit there only if it first sent a message 'new.message'. That's why, in your browser, the client originating the message is the only one receiving it back.
Change it to:
socket.on('new.message', function(message) {
io.sockets.emit('new.message', message);//use this if even the browser originating the message should be updated.
socket.broadcast.emit('new.message', message);//use this if everyone should be updated excpet the browser source of the message.
})
Here are the different ways you can emit:
io.sockets.on('connection', function(socket) {
//This message is only sent to the client corresponding to this socket.
socket.emit('private message', 'only you can see this');
//This message is sent to every single socket connected in this
//session, including this very socket.
io.sockets.emit('public message', 'everyone sees this');
//This message is sent to every single connected socket, except
//this very one (the one requesting the message to be broadcasted).
socket.broadcast.emit('exclude sender', 'one client wanted all of you to see this');
});
You can also add sockets to different rooms when they connect so that you only communicate messages with sockets from a given room:
io.sockets.on('connection', function(socket) {
//Add this socket to a room called 'room 1'.
socket.join('room 1');
//This message is received by every socket that has joined
//'room 1', including this one. (Note that a socket doesn't
//necessarily need to belong to a certain room to be able to
//request messages to be sent to that room).
io.to('room 1').emit('room message', 'everyone in room 1 sees this');
//This message is received by every socket that has joined
//'room 1', except this one.
socket.broadcast.to('room 1').emit('room message', 'everyone in room 1 sees this');
});

nodejs socket.io - connected to server but emit doesn't do anything

I'm starting to work with Socket.io and my nodeJS API
I succeeded to get my user connected, and showed a message on my server.
But now, I'm trying to send data to my client -> then server -> then client again etc.
But when I use emit nothing appends... So this i my code :
SERVER SIDE
io.on('connection', function(socket){
console.log("user connected") // I see that
socket.emit('text', 'it works!'); //
socket.on('test1', function (data) {
console.log('received 1 : '); // Never showed
console.log(data); // Never showed
});
}
CLIENT SIDE
var socket = io.connect(myUrl); // good connection
socket.emit ('test1', {map: 4, coords: '0.0'}); // never showed on the server side
socket.on('text', function(text) {
alert(text); // never showed
socket.emit('test', { "test": "test2" });
});
Any ideas?
thanks !
Your Starter Code seems to be valid, you need to check two things :
if you successfully included the socket.min.js in the client side
if you re having any error printed in the console
On the client side, you have to wait until the connection succeeds before it is safe to send data to the server. Connecting to the server is not synchronous or instantaneous (thus it is not ready immediately). You are trying to send data before the connection is ready.
Put your first send of data inside a socket.on('connect', ...) handler.
var socket = io.connect(myUrl); // good connection
// send some data as soon as we are connected
socket.on('connect', function() {
socket.emit ('test1', {map: 4, coords: '0.0'});
});
socket.on('text', function(text) {
alert(text); // never showed
socket.emit('test', { "test": "test2" });
});
this worked for me
CLIENT SIDE
//sending custom data to server after successful connection
socket.on('connect', function(){
this.socket.emit('client-to-server', {map: 4, coords: '0.0'});
});
//listening the event fired by the socket server
socket.on('server-to-client', function(dataSendbyTheServer){
// do whatever you want
console.log(dataSendbyTheServer);
});
SERVER SIDE
io.on('connection', function(socket) {
// listening the event fired by the client
socket.on('client-to-server', function (data) {
console.log('received 1 : ');
// sending back to client
io.emit('server-to-client', data)
});
});

Sending message to specific client in Socket IO

I'm using Socket IO v1.4.5 and have tried 3 different ways below but dont have any result.
client.emit('test', 'hahahaha');
io.sockets.socket(id).emit('test',''hahaha);
io.sockets.connected[id].emit('test','hahaha');
Here is my server side
var socket = require( 'socket.io' );
var express = require( 'express' );
var http = require( 'http' );
var dateFormat = require('date-format');
var app = express();
var server = http.createServer( app );
var io = socket.listen( server );
io.sockets.on( 'connection', function( client ) {
user[client.id]=client;
//when we receive message
client.on('message', function( data ) {
console.log( 'Message received from' + data.name + ":" + data.message +' avatar' +data.avatar );
client.emit('test', 'hahahaha');
});
Any help would be great.Thanks for help.Kind Regard
To send a message to a specific client you need to do it like so:
socket.broadcast.to(socketid).emit('message', 'for your eyes only');
Here is a nice little cheat sheet for sockets:
// sending to sender-client only
socket.emit('message', "this is a test");
// sending to all clients, include sender
io.emit('message', "this is a test");
// sending to all clients except sender
socket.broadcast.emit('message', "this is a test");
// sending to all clients in 'game' room(channel) except sender
socket.broadcast.to('game').emit('message', 'nice game');
// sending to all clients in 'game' room(channel), include sender
io.in('game').emit('message', 'cool game');
// sending to sender client, only if they are in 'game' room(channel)
socket.to('game').emit('message', 'enjoy the game');
// sending to all clients in namespace 'myNamespace', include sender
io.of('myNamespace').emit('message', 'gg');
// sending to individual socketid
socket.broadcast.to(socketid).emit('message', 'for your eyes only');
Credit to https://stackoverflow.com/a/10099325
The easiest way rather than sending directly to the socket, would be creating a room for the 2 users to use and just send messages freely in there.
socket.join('some-unique-room-name'); // Do this for both users you want to chat with each other
socket.broadcast.to('the-unique-room-name').emit('message', 'blah'); // Send a message to the chat room.
Otherwise, you're going to need to keep track of each individual clients socket connection, and when you want to chat you'll have to look up that sockets connection and emit specifically to that one using the function I said above. Rooms are probably easier.
Socket.io Version 2.0.3+
Sending a message to a specific socket
let namespace = null;
let ns = _io.of(namespace || "/");
let socket = ns.connected[socketId] // assuming you have id of the socket
if (socket) {
console.log("Socket Connected, sent through socket");
socket.emit("chatMessage", data);
} else {
console.log("Socket not connected, sending through push notification");
}
Simply do this
io.socket.in('room').emit("send message to everyone", data);

Node.js TCP socket waits seconds before polling? (net.createServer)

I have a very simple TCP socket in Node.js. It connects to a device that sends data back in XML format. There is a C# program that does this same trick, but I had to build it in Node.js.
So, when the device sends a message, I'm getting the response about 5 seconds later! Where the C# program gets it 1 or 2 seconds later.
It looks like the 'tcp socket' has a specific polling frequency or some kind of 'wait function'. Is that even possible? Everytime an incoming message displays. It also display's the exit message of "sock.on('close')"
It seems that after 5 seconds the 'server' automaticly closes. See bottom lines "console.log('[LISTENER] Connection paused.');" After that, the incoming message gets displayed correctly.
What is wrong with my code?
// Set Node.js dependencies
var fs = require('fs');
var net = require('net');
// Handle uncaughtExceptions
process.on('uncaughtException', function (err) {
console.log('Error: ', err);
// Write to logfile
var log = fs.createWriteStream('error.log', {'flags': 'a'});
log.write(err+'\n\r');
});
/*
-------------------------------------------------
Socket TCP : TELLER
-------------------------------------------------
*/
var oHOST = '10.180.2.210';
var oPORT = 4100;
var client = new net.Socket();
client.connect(oPORT, oHOST, function() {
console.log('TCP TELLER tells to: ' + oHOST + ':' + oPORT);
// send xml message here, this goes correct!
client.write(oMessage);
});
// Event handler: incoming data
client.on('data', function(data) {
// Close the client socket completely
client.destroy();
});
// Event handler: close connection
client.on('close', function() {
console.log('[TELLER] Connection paused.');
});
/*
-------------------------------------------------
Socket TCP : LISTENER
-------------------------------------------------
*/
var iHOST = '0.0.0.0';
var iPORT = 4102;
// Create a server instance, and chain the listen function to it
var server = net.createServer(function(sock) {
// We have a connection - a socket object is assigned to the connection automatically
console.log('TCP LISTENER hearing on: ' + sock.remoteAddress +':'+ sock.remotePort);
// Event handler: incoming data
sock.on('data', function(data) {
console.log('Message: ', ' '+data);
});
// Event handler: close connection
sock.on('close', function(data) {
console.log('[LISTENER] Connection paused.');
});
}).listen(iPORT, iHOST);
client.write() does not always transmit data immediately, it will wait until buffers are full before sending the packet. client.end() will close the socket and flush the buffers.
You could try this: http://nodejs.org/api/net.html#net_socket_setnodelay_nodelay
Your 5 second delay does seem a bit weird, though.
So within the "TELLER" I had to write "sock.write(data);" inside the "sock.on('data', function(data)" event.
It works now. Thanks Jeremy and rdrey for helping me in the right direction.

Resources