How to emit a socket.io response within post request in NodeJS - javascript

I have a node server running a react application, integrated with Socket.io. All works fine. I also have an external application that uses the same data. What I want to do is, when the data changes, post to my node server and then in the response, emit to any data to users who are currently subscribed to the socket.
//SERVER CODE LIVES ABOVE HERE...
const io = require('socket.io')(server);
io.on('connection', (socket) => {
socket.on('create data', function(data) {
//a place to create data, once complete triggers everyone subscribed to get an update.
socket.emit('data created', data);
});
});
app.post('/api/datacreated/', function(req, res) {
//HOW DO I EMIT IN HERE?! - this is coming from an external resource
socket.emit('data created', data);
})
Cheers for any time you've got!

Socket is locally scoped. io.sockets is not, so you can do:
app.post('/api/datacreated/', function(req, res) {
//this is coming from an external resource
io.sockets.emit('data created', data);
})

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.

socket.io fails to emit in express app.post callback

I have an express application that opens up a socket connection with my frontend React application.
I want to emit an event to the connected socket whenever someone sends a post request to my server with json data but socket.emit doesn't fire in a.post callback. io.sockets.emit however works fine but is of no use to me in this case.
This fails:
io.on('connection', (socket) => {
app.post('/event', (req, res) => {
socket.emit('someevent', req.body);
res.sendStatus(200);
}
}
But this passes:
io.on('connection', (socket) => {
app.post('/event', (req, res) => {
io.sockets.emit('someevent', req.body);
res.sendStatus(200);
}
}
SLaks's comment is correct but it did not help me solve my problem.
What I ended up doing is:
In the post request coming to /event from the client, I added a hidden input field containing the ID of socket connection.
Then in my /event route handler, I did:
app.post('/event', function(req, res) {
io.sockets.in(req.body.socketId).emit('someevent', req.body);
res.sendStatus(200);
});
This works because by default each socket connection joins a room identified with its socket-id and messages can be sent to rooms using the io object iteself (no need to obtain a socket object from io.on('connection', socket =>{})

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.

How does nodejs usually manipulate DOM from the backend without using socket

Usually what I would do is
In backend
socket.emit("manipulate", data);
In frontend
socket.on("manipulate", data);
So that you can signal Jquery to manipulate the DOM in frontend
However because I want to manipulate the DOM in app.js where
FILES
app.js
backend.js
ui.js
app.js
app.post('/test', function(req, res){
res.sendfile(__dirname + '/views/test.html');
Backend.manipulate(req.body, function(err, data){
if (err) throw err;
// how do I manipulate DOM here
});
});
backend.js
exports.listen = function(server){
io = socketio.listen(server);
io.set('log level', 2);
io.sockets.on('connection', function(socket){
});
}
I don't have access to socket, and I can't move exports.listen as all my socket manipulation is there.
Any advice would be appreciated
Edit:
For clarification on the use case, say that I have a registration form in the front end, the registration is submit through POST, and POST calls a function in backend.js that register the user, after backend.js succesfully register the user it would like to send a message to the user, how would that message normally be display in frontend?

Categories