Broadcast an HTML page to clients in Nodejs with Express - javascript

I am developing a client-server app with Nodejs and Express. I'd like to send an HTML page (for example index.html) to all the clients connected to the server.
The server allows the user to log in with name and password, this connection data are stored with an array just like this:
app.post('/myaction', function(req, res) {
clients.push({
"name": req.body.nombre,
"direction":req.connection.remoteAddress,
"time": getDate(),
"role" : role
});
}
So the IP directions are stored in this array too. I can loop with a forEach loop:
clients.forEach(function (client) {
});
Which Express function allows me to send an HTML document to all these clients stored in the array?

You can't achieve that using express. The best approach is to use websockets to push data to all connected clients. I recommend using Socket.io for that since it's really simple to use.
const app = require('express')();
const server = require('http').Server(app);
const io = require('socket.io')(server);
io.on('connection', socket => {
console.log('User connected');
});
app.post('/myaction', (req, res) => {
io.emit('data', 'some-data');
res.send('Data sent to all connected users');
});
client side
// Add socket.io client side library
var socket = io();
socket.on('data', function(data) {
// Do something with the data sent from the server
});

Related

How to read response in server after sending an alert to specific user in socket.io?

I'm new to Socket.io. Here is my problem.
I want to get the real time location of Android device. So I created a simple app to get current GPS location. And Node.js server and also Angular Admin panel.
Here is my Node.js server code.
//Some import statements are missing here. Not added.
var app = require('express')();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
// Creating the socket connection.
io.sockets.on('connection', function (socket) {
socket.on('join', function (data) {
socket.join(data.id);
});
});
module.exports = function (app, express) {
var api = express.Router();
api.post('/device_location/:child_id', function (req, res) {
var child_id = req.body.child_id;
io.sockets.in(child_id).emit('new_msg', {msg: 'gps_data'}); //Sending request to registered android device.
var gps_location = ""; //Here i want to take GPS data from android client.
res.json({ type: "success", code: 200, data: gps_location }); //Then i can send the response to anyone who need that.
});
return api;
};
If this is not clear, please check this gist : https://gist.github.com/chanakaDe/123080fa5427c38c37f36afdac10be7c
First I created the socket connection. Then Android client can connect to it with unique user ID.
Then I'm sending the request to get GPS data when admin press the button from the Administration button.
io.sockets.in(child_id).emit('new_msg', {msg: 'gps_data'});
Here, child_id is the ID of android application.
Then I want to get the response from Android app and read it in server.
After reading that, I can send that to anyone asking for it.
res.json({ type: "success", code: 200, data: gps_location });
This is the normal Node.js way of sending a response.
How can we get the response to this var gps_location = ""; variable which we are getting GPS value of specific user.
Please help me on this. Tried many ways, but not good. I just need to read the response from Android client in the server and process it.
You need to emit your GPS location from Android to your server using something like :
socket.emit("gpsdata", data)
and then receive it in Node using socket.on("gpsdata", doSomething) :
io.sockets.on('connection', socket => {
socket.on("gpsdata", data => { // Receive data from one socket
io.sockets.emit('gps_location', { gps_location : data }) // Emit to everyone
})
});
https://socket.io/docs/emit-cheatsheet/

How to change URL Websocket NodeJs (server/client)

I have a server node Js with express I want to use two socket with my clients in the same page server.js (contains all my controllers), suddenly I want to put the first socket under the url ("/connection"), and A second one under the url ("/giveUserConnected") that will serve me to recupir the connected users, par exemple :
client.html :
var socket = io.connect('http://127.0.0.1:9999/connection');
To contact server.js :
app.get('/connection',function (req,res) {
io.on('connection', function(socket){
console.log('a user connected');
});
});
and another socket2 in client.html :
var socket2 = io.connect('http://127.0.0.1:9999/giveUserConnected');
to contact server.js :
app.get('/giveUserConnected',function (req,res) {
io.on('connection', function(socket){
// to recuper list of users connected
});
});
but it does not work
what is the solution , thank's
You are mixing HTTP requests with socket.io requests, which are two different things.
When you provide a path name to io.connect() (in this case, /connection and /giveUserConnected), the socket.io server uses the path as the name to a namespace that the client connects to.
What I think you want is to just create an event handler for a particular message that will return the list of users. You could use acknowledgement functions for that:
// server
io.on('connection', function(socket) {
socket.on('giveUserConnected', function(fn) {
fn(listOfUsers);
});
});
// client
socket.emit('giveUserConnected', function(users) {
...
});
What listOfUsers is depends on your app.

JS Socket | Add full array on the site

So I have a kinda bug on my socket system. I have a array which will be emited if new connection is made to the site, but the problem is that it will be called on all users. So if I have there console.log('new user') then everyone will receive it to the console. My question is, how can I do it so the only one user who just connected receives only it?
Here is my server
io.on('connection', function(client){
clients.push(client.id);
io.emit('add games', coinflips); //This is the line
console.log(clients);
client.on('disconnect', function(){
clients.splice(client.indexOf, 1);
console.log(clients);
});
});
Here is how it's being handled
socket.on('add games', function(data){
if(data.length > 0){
addGames(data);
}
});
you can use the the socket id, socket.id then send to that id.
something along this line.
io.of('/mynamespace').sockets[socketID].emit(...)
Event this logic could work
clients = [];
then whenever a connection is made.
clients.push(socket);
then in the clients array, just index it.
clients[0].emit(...)
this is how you get a id upon connection.
console.info('Client id (id=' + socket.id + ').');
Socket.IO allows you to “namespace” your sockets, which essentially means assigning different endpoints or paths.
Namespaces are useful features to minimize the number of resources (TCP connections) and at the same time separate concerns within your application by introducing separation between communication channels. Multiple namespaces actually share the same WebSockets connection thus saving us socket ports on the server.
Namespaces are created on the server side. But they are joined by clients by sending a request to the server.
---------------------------------------------------------------
Default Namespaces
The root namespace '/' is the default namespace which is joined by clients if a namespace is not specified by the client while connecting to the server. All connections to the server using the socket object client side are made to the default namespace.
--------------------------------------------------------
Custom Namespaces
We can create our own custom namespaces. To set up a custom namespace, we can call the of function on the server-side:
---------------------------------------------------------
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res){
res.sendfile('index.html');
});
var nsp = io.of('/my-namespace');
nsp.on('connection', function(socket){
console.log('someone connected');
nsp.emit('hi', 'Hello everyone!');
});
http.listen(3000, function(){
console.log('listening on localhost:3000');
});

How can I establish one connection between a user and the WebSocket?

I have websocket running on a node/Express server.
I need to send json string back and fourth between a websocket and a client.
However, if a user opens more than one browser's tab, I like for the websocket server to know that this is the same user that is already connected.
Here is the logic execution order
A user connects to the WebSocket.
The user sends json string to the WebSocket.
The WebSocket does things to the received message.
WebSocket finally sends the new message to all the tabs that a user have open.
The new message should be returned only to that user not others.
How can I establish one connection between a user and the WebSocket?
This is my server setup
var env = require('./config');
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var clients = [];
server.listen(env.socket.port, env.socket.host, function () {
var host = server.address().address;
var port = server.address().port;
console.log('Websocket running at http://%s:%s', host, port);
});
app.get('/', function (req, res) {
res.send('Welcome!');
});
io.on('connection', function (socket) {
clients[] = socket;
socket.emit('chat', { hello: 'world' });
socket.on('chat', function(msg){
console.log('message: ' + msg);
sendAll(msg);
});
});
function sendAll (message) {
for (var i=0; i< clients.length; i++) {
clients[i].send("Message For All: " + message);
}
}
If you do not have authentication for the users, then you need some browser-specific piece of data to correlate users on your backend.
I don't know about cookies (haven't used them), but one way at the JavaScript level would be to store a locally generated random ID (of sufficient length so that you don't have to worry about collisions) in local storage in the browser, and transmit this as part of the initial message at the WebSocket level.

Client not updating realtime with Socket.io and Node.js

Why isn't my client side updating automatically using socket.io and node.js?
My backend accepts JSON POST requests from PHP, then it emits the data to all connected devices.
My backend code
app.post('/', function (req, res) {
console.log(req.body);
subdata = req.body;
res.send('ok');
});
io.sockets.on('connection', function (socket) {
socket.broadcast.emit('info', subdata);
});
Client side
<script>
var socket = io.connect('http://127.0.0.1:3000/');
socket.on('info', function (data) {
console.log(data);
});
</script>
That's because you only ever emit once when a new socket.io connection is made. If the app.post callback is called again, there's nothing to emit another message from socket.io.
You want to emit from within your app.post callback, and stop using global variables.

Categories