How use socket.io in express routes with node.js - node.js

I'm using Express with Socket.io in the server side but i can't use out of app.js, i need how to use SocKet.io in Express routes.
app.js
...
let http = require('http').Server(app);
let io = require('socket.io')(http);
io.on('connection', (socket) => {
console.log('user connected');
socket.on('disconnect', function(){
console.log('user disconnected');
});
socket.on('message', (message) => {
console.log("Message Received: " + message);
io.emit('message', {type:'new-message', text: message});
});
});
...
this work ok, but i have other routes where configure my methods, POST, GET ... EX
routesActividad.js
...
function http(){
this.configActividad= function(app){
// get actividades by id
app.get('/actividad/:NUM_ID_EMPLEADO', function(req, res) {
//... code here...//
.then(function (actividad) {
res.json(actividad);
}).catch(error => res.status(400).send(error));
})
app.post('/actividad/', function(req, res){
// code here //
})
app.put('/actividad/', function(req, res){
// code here //
})
}
}
module.exports = new http();
how i can use socket in routesActividad.js and other routes like this, for use emit or scoket.on y this routes
app.js
...
var routesActividad = require('./routes/routesActividad');
routesActividad.configActividad(app);
// more routes
...
thanks

Hello you just need to pass the IO instance by parameter to your external module:
app.js
let http = require('http').Server(app);
let io = require('socket.io')(http);
let actividad = require('routesActividad')(io);
routesActividad.js:
function http(io){
//put the IO stuff wherever you want inside functions or outside
this.configActividad= function(app){
// get actividades by id
app.get('/actividad/:NUM_ID_EMPLEADO', function(req, res) {
//... code here...//
.then(function (actividad) {
res.json(actividad);
}).catch(error => res.status(400).send(error));
})
app.post('/actividad/', function(req, res){
// code here //
})
app.put('/actividad/', function(req, res){
// code here //
})
}
}
module.exports = http; //Removed new statement

Related

Using socket.io with express.js controller

I am trying to use socket.io with controller functions in express.js, but the socket.on is not calling into the io.on() in server.js
// at server.js
const postRoute = require('./routes/postReqRouter')
io.on('connection', function (socket) {
console.log('=====SOCKET Connected======', socket.id)
socket.on('taskDataSOCK', function (data) {
console.log('====TaskData Found====', data)
io.emit('taskDataSOCK', { data })
})
}
app.use(function (req, res, next) {
res.io = io
next()
})
app.use('/api/post', postRoute)
// postReqRouter.js
router.route('/get-all-data').post(contoller.getData)
module.exports = router
// at controller.js
exports.getData = (req, res) => {
/// `enter code here`
res.io.emit(‘'taskDataSOCK', { data })
}
The io.on('connection') is called when a client is connected you can connect to the same socket server using client (frontend) or from another nodejs app see here

Socket.io emit not working (by visiting URL)

I am developing an app that gets a signal from external hardware equipment. I catch this signal by redirecting it to a certain URL in my app: '/impulse/:id'.
I am able to catch the signal, but the emit function inside the app.get('/impulse/:id') is not triggering. The console logs are...
How can I make the emit function work?
Below is my server.js script, where I catch all the socket signals and prevent the external call from being redirected to the index page.
...
const express = require('express');
const app = express();
const port = process.env.PORT || 8080;
const socket = require('socket.io');
app.use(express.static(__dirname + '/public'));
app.use('/api', appRoutes);
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://HERE IS MY DB INFO...', function(err) {
if (err) {
console.log('Not connected to the database: ' + err); // Log to console if unable to connect to database
} else {
console.log('Successfully connected to MongoDB'); // Log to console if able to connect to database
}
});
var server = app.listen(port, function() {
console.log('Running the server on port ' + port); // Listen on configured port
});
var io = socket(server);
io.on('connection', function(socket){
socket.on('join', function(data){
var gameroom = data.gameid;
console.log("joined: " + gameroom)
socket.join(gameroom);
})
//FUNCTION I WANT TO TRIGGER
socket.on('impulse', function(data){
console.log('IMPULSE')
io.emit('impulseReceived', {
})
})
})
//PLACE WHERE I EMIT
app.get('/impulse/:id', function(req, res){
console.log('Impulse Received')
var time = req.query.TIME;
var gameroom = req.params.id;
io.on('connect', function (socket) {
socket.emit('impulse', {
})
})
res.json({ success: true, message: 'received the time!'})
})
app.get('*', function(req, res) {
res.sendFile(path.join(__dirname + '/public/app/views/index.html')); // Set index.html as layout
});
Replace this whole
io.on('connect', function (socket) {
socket.emit('impulse', {
})
}
with this
io.emit('impulse', {})

app post is not working i am not getting the output

var express = require("express");
var app = express();
var bodyParser = require('body-parser');
var port = 3000;
const fs = require('fs');
// we are connecting to the mangodb using mangoose
var mongoose = require("mongoose");
// Now we are using bodyParser
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
mongoose.connect("mongodb://localhost:27017/YourDB", { useNewUrlParser: true })
// now we are creating the schema to the database
var nameSchema = new mongoose.Schema({
firstName: String,
lastNameName: String
});
// Now we have to create a model
var User = mongoose.model("User", nameSchema);
app.use("/", (req, res) => {
res.sendFile(__dirname + "/index.html");
});
// Now we are posting the data
app.post("/addname", (req, res) => {
console.log("nnnnnn")
console.log(req.body.firstName)
var myData = new User(req.body);
myData.save()
console.log(myData);
fs.writeFile(__dirname +"/data.json",myData, function(err){
if(err) {
return console.log(err);
}
console.log("The file is saved ");
})
console.log(myData)
})
// Now we are getting the data
app.listen(port, () => {
console.log("Server listening on port " + port);
});
1)I am using express app.post to post the data into database and store the data into the write file to check
2) app.post is not working it tried console.log to check but it is not going inside the function
3) I am not getting output as well as any error plese help me
there is no error handling and response handling in this code.
it will be readable if we write post method with async/await :
app.post("/addname", async (req, res) => {
console.log("nnnnnn")
console.log(req.body.firstName)
var myData = new User(req.body);
await myData.save()
console.log(myData);
fs.writeFileSync(__dirname +"/data.json", myData)
console.log(myData)
})
you will add next() to app.use
var User = mongoose.model("User", nameSchema);
app.use("/", (req, res,next) => {
res.sendFile(__dirname + "/index.html");
next()
});
// Now we are posting the data
app.post("/addname", (req, res) => {
console.log("nnnnnn")
console.log(req.body.firstName)
var myData = new User(req.body);
myData.save()
console.log(myData);
fs.writeFile(__dirname +"/data.json",myData, function(err){
if(err) {
return console.log(err);
}
console.log("The file is saved ");
})
console.log(myData)
})
// Now we are getting the data
app.listen(port, () => {
console.log("Server listening on port " + port);
});
That's because every request is going to this app.use code block. app.use("/", (req, res) => { ... });
Just Put it below the app.post("/addname", (req, res) => { ... });
app.use is used to mount middlewares into the request-response chain. So, every request that comes matches the /(which is essentially every request) goes inside that middleware. So, use your routes first then use the middleware at the end.
EDIT:
Let me give you a mcve which I tested locally:
const express = require('express');
const fakeData = function(){
return {
s: "fakeData"
}
}
const app = express();
const port = 8181
const path = require('path')
app.get("/a", (req, res) => {
return res.json({d:'yay'});
});
app.use('/',(req,res)=>{
return res.json(fakeData());
})
app.listen(port, () => {
console.log(`Server started on PORT ${port}`);
});
Because every request goes through a mounted middleware, so when you GET/POST/ANYTHING to localhost:8181/<abosulutely_any_path> it will go through the app.use because it treats that function as middleware and will return { s: "fakeData" }.
But when you make a GET call http://localhost:8181/a it will go to the app.get route BECAUSE WE DECLARED IT FIRST and return { d : "yay" }

'Sharing' object between NodeJS modules

I'm new to NodeJS development and I'm doing some tests with the socket.io library. Basically, what I want to do is to stablish a socket.io connection between the clients (Angular 6 web app) and the server and broadcast a message when a new user connects.
Right now, the code is quite simple, and this is what I have:
app.js
var express = require('express');
var http = require('http');
var socketIO = require('socket.io');
// Routes
var twitterRoutes = require('./routes/user');
var app = express();
var server = http.Server(app);
var io = socketIO(server); // <== THIS OBJECT IS WHAT I WANT TO USE FROM THE ROUTES
[ ... ]
io.on('connect', (socket) => {
console.log('New user connected');
socket.on('disconnect', (reason) => {
console.log('User disconnected:', reason);
});
socket.on('error', (err) => {
console.log('Error in connection: ', err);
});
});
I want to use the io object inside the user route, but I don't know how to do it:
routes/user.js
var express = require('express');
var config = require('../config/config');
var router = express.Router();
router.post('/login', (req, res, next) => {
// DO ROUTE LOGIC
// I WANT TO BROADCAST THE NEW LOGGED USER USING io.broadcast.emit, BUT DON'T KNOW HOW
// <=====
});
How could I do it? Thanks in advance,
Not sure if it is the best way but you could share things between request handlers using middleware
// define and use a middleware
app.use(function shareIO(req, res, next) {
req.io = io;
next();
})
Then you could use req.io inside request handlers.
router.post('/login', (req, res, next) => {
// DO ROUTE LOGIC
req.io.emit('event')
});
You could do what you want by injecting your IO var in a function
// app.js
var app = express();
var server = http.Server(app);
var io = socketIO(server);
server.use(require('./router')(io))
...
// router.js
module.exports = function makeRouter(io) {
var router = express.Router();
router.post('/login', (req, res, next) => {
// do something with io
}
return router
}
I don't know if it's the best practice, but I've assigned the io object to a property of the global object, and I can access it from everywhere all across the application. So this is what I did:
app.js
var io = socketIO(server);
global.ioObj = io;
routes/user.js
router.post('/login', (req, res, next) => {
// DO ROUTE LOGIC
if (global.ioObj) {
global.ioObj.sockets.clients().emit('new-message', { type: 'message', text: 'New user has logged in' });
}
});

How to receive posts from Instagram API using Express.js on Node

I am trying to set up an app that will show Instagram posts in real time with a certain hashtag.
Here's what I have thus far.
var io = require('socket.io').listen(app)
, fs = require('fs')
, connect = require('connect')
, $ = require('jquery')
// , ngrok = require('ngrok')
, express = require('express')
, app = express()
, port = process.env.PORT || 5000;
//ngrok.connect(5000, function (err, url) {
//})
app.listen(port);
function handler (req, res) {
fs.readFile(__dirname + '/index.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.emit('stuff', function() {
console.log("http server listening on %d", port);
});
socket.on('my other event', function (data) {
console.log(data);
});
});
// Defining Routes
app.use(express.static(process.cwd() + '/public'));
app.get('/', function (req, res) {
res.send('Testing');
});
app.get('/endpoint', function (req, res) {
// For convention's sake, we only respond to this if it's a properly formatted request from Instagram
if (req.query['hub.challenge']) {
// First we check if hub.challenge exists in the query, then we do something
res.send(req.query['hub.challenge']);
}
});
This is where I'm wrong/lost
app.use(express.bodyParser());
app.post('/endpoint', function (req, res) {
console.log(req.body);
});
I believe I've followed the Subscription tutorial in the Instagram API (set up hub.challenge and set up a subscription) but how do I see the incoming JSON data it's supposed to send? On top of that, how can I manipulate the JSON to show the pictures on the front end?
Any help is appreciated!

Resources