breake timer on socket event - node.js

I need to break a timer on a socket event and my Nodejs Express Socket.io App looks like this:
app.js
const express = require('express') ;
const app = express();
const server = require('http').Server(app);
const io = require('socket.io')(server);
const api = require('./routes/api');
const users = io.of('/users') ;
const usersNamespace= (socket) => {
socket.on('disconnect',()=>{
});
}
users.on('connection',usersNamespace) ;
app.use('/api', api);
// make socket.io accessible in the express router
app.use((req,res,next)=>{
req.io = io;
req.users = users;
next();
});
server.listen('8000');
my ./routes/api.js file looks like:
var express = require('express');
var router = express.Router();
router.post('/test',req,res) {
// broadcast body of request to users namespace
req.users.emit('restreq',req.body) ;
var timer = setInterval(()=>{
console.log('hello');
}, 5000);
res.status(200).json('received') ;
}
module.exports = router;
The question is how i can do clearInterval and stop the timer on a receiving socket event?

You can pass a function or object to deal with intervals as you do with users:
app.js
const express = require('express') ;
const app = express();
const server = require('http').Server(app);
const io = require('socket.io')(server);
const api = require('./routes/api');
const users = io.of('/drivers') ;
const timer = {
hInterval: null,
register: hInterval => {
timer.hInterval = hInterval
},
disable: () => {
clearInterval(timer.hInterval)
timer.hInterval = null
}
}
const usersNamespace = socket => {
socket.on('disconnect', () => {
timer.disable()
});
}
users.on('connection', usersNamespace) ;
app.use('/api', api);
// make socket.io accessible in the express router
app.use((req, res, next)=>{
req.io = io;
req.users = users;
req.timer = timer;
next();
});
server.listen('8000');
api.js:
var express = require('express');
var router = express.Router();
router.post('/test', req,res) {
// broadcast body of request to users namespace
req.users.emit('restreq',req.body) ;
req.timer.register(setInterval(() => {
console.log('hello');
}, 5000));
res.status(200).json('received') ;
}
module.exports = router;

Related

Video stream from client to server in NodeJS

I'm currently developing an application to stream video feed from client to server in NodeJS. The server side code is as shown below
server.js
const express = require('express')
const app = express()
const morgan = require('morgan')
const server = require('http').Server(app)
const io = require('socket.io')(server)
const auth = require('./routes/auth')
const video = require('./routes/videoproc')(io)
const bodyParser = require('body-parser')
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: true}))
app.use(morgan('dev'))
app.use("/users", auth)
app.use("/exam", video);
server.listen(3000)
videoproc.js
const express = require('express')
const video = express.Router()
const ss = require('socket.io-stream')
const fs = require('fs')
const path = require('path')
module.exports = (io) => {
video.post('/video', (req, res) => {
io.on('connection', (socket) => {
ss(socket).on('video', (stream, data) => {
const fileName = path.basename('test')
stream.pipe(fs.createWriteStream(fileName))
})
})
})
return video
}
This is the client side code
var io = require('socket.io-client');
var ss = require('socket.io-stream');
var fs = require('fs')
var socket = io.connect('http://localhost:3000/exam/video/');
var stream = ss.createStream();
var filename = './test.webm';
ss(socket).emit('video', stream, {name: filename});
fs.createReadStream(filename).pipe(stream);
As a test I've send a video feed to the server but the file is not being stored, some help to solve this issue is appreciated.
Server you should:
const bodyParser = require('body-parser')
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: true}))
app.use(morgan('dev'))
// app.use("/users", auth)
app.use("/exam", video);
io.on('connection', (socket) => {
console.log('CONNECTED');
ss(socket).on('video', (stream, data) => {
console.log('RECEIVED');
const fileName = path.basename('test')
stream.pipe(fs.createWriteStream(fileName))
})
})
server.listen(3000)
and Client: param in a connect function is just "http://localhost:3000/", exclude route
var socket = io.connect('http://localhost:3000/');
var stream = ss.createStream();
var filename = './test.webm';
ss(socket).emit('video', stream, {name: filename});
fs.createReadStream(filename).pipe(stream);
At client: connect to a domain, not route:
ref
At server: you placed io.on on a route, io.on is just listen when you call the route. if you want run when server starting, you should place io.on outside the route

How to use socket io with node.js

I have deployed an app with Heroku. I have a chat. It work fine in local but not with the online app.
index.js in my server :
const express = require('express');
const bodyparser = require('body-parser');
const security = require('./middleware/security');
const userRouter = require('./routes/user');
const AnnonceRouter = require('./routes/annonce');
const securityRouter = require('./routes/security');
const commentRouter = require('./routes/comment');
const mailRouter = require('./routes/mail')
const path = require('path');
const isDev = process.env.NODE_ENV !== 'production';
const PORT = process.env.PORT || 5000;
const app = express();
const cors = require('cors');
var chat = require('https').createServer(app)
var io = module.exports.io = require('socket.io')(chat)
const SocketManager = require('./SocketManager')
io.on('connection', SocketManager)
if (process.env.NODE_ENV === 'production') {
app.use(express.static('../client/build')); // serve the static react app
app.use(cors());
app.use(bodyparser.json());
app.use(security.verifyToken);
app.use('/annonce', AnnonceRouter);
app.use('/user', userRouter);
app.use('/comment', commentRouter);
app.use('/mail', mailRouter);
app.get(/^\/(?!api).*/, (req, res) => { // don't serve api routes to react app
res.sendFile(path.join(__dirname, '../client/build/index.html'));
})
app.use('/', securityRouter);;
console.log('Serving React App...');
};
app.listen(PORT, function () {
console.error(`Node ${isDev ? 'dev server' : 'cluster worker '+process.pid}: listening on port ${PORT}`);
});
the file when i use it
const socketUrl = "https://teachonline.herokuapp.com"
export default class Layout extends React.Component {
constructor(props) {
super(props);
this.state = {
socket:null,
user:null
};
}
componentWillMount() {
this.initSocket()
}
/*
* Connect to and initializes the socket.
*/
initSocket = ()=>{
const socket = io(socketUrl)
socket.on('connect', ()=>{
console.log("Connected");
})
this.setState({socket})
}
I tried something different, but the result is still the same.
My request looks like that : https://teachonline.herokuapp.com/socket.io/?EIO=3&transport=polling&t=MpFHcqj
But i get a code 401 "Unauthorized"
If you have an idea of what am i doing wrong, i'm listening.
Instead of PORT_CHAT, use PORT.
const isDev = process.env.NODE_ENV !== 'production';
const PORT = process.env.PORT || 5000;
const PORT_CHAT = 3231;
const app = express();
const cors = require('cors');
var chat = require('https').createServer()
var io = module.exports.io = require('socket.io')(chat)
const SocketManager = require('./SocketManager')
io.on('connection', SocketManager)
chat.listen(PORT, ()=>{
console.log("Connected to port:" + PORT);
})

TypeError: Cannot read property 'listOrderJson' of undefined

Im trying to link a route to a controller vs doing the code within the route definiton. Here is my controller:
const {mongoose} = require('../db/mongoose');
const {Order} = require('../models/order');
module.exports.listAllJson = function(req, res) {
res.send({"Here": "something"});
}
And here is my server.js file:
var express = require('express');
var bodyParser = require('body-parser');
var fs = require('fs');
var schedule = require('node-schedule');
var {mongoose} = require('./db/mongoose');
var {Order} = require('./models/order');
var {orderController} = require('./controllers/orderController');
var app = express();
app.use(bodyParser.json());
app.get('/orders', (req, res) => {
orderController.listAllJson().bind(orderController);
});
app.listen(3000, () => {
console.log('Started on port 3000');
});
module.exports = {app};
When I hit my /orders route using postman I get:
TypeError: Cannot read property 'listOrderJson' of undefined error.
I added the 'bind' part to the function call after searching here on stack overflow a ton, but it didn't help. What am I doing wrong here?
orderController is { listAllJson: fn } so you can simply destructure and use it.
var express = require('express');
var bodyParser = require('body-parser');
var fs = require('fs');
var schedule = require('node-schedule');
var {mongoose} = require('./db/mongoose');
var {Order} = require('./models/order');
var {listAllJson} = require('./controllers/orderController');
var app = express();
app.use(bodyParser.json());
app.get('/orders', listAllJson);
app.listen(3000, () => {
console.log('Started on port 3000');
});
module.exports = {app};
Also minor note use res.json({"Here": "something"}); it does the stringifying and set the headers.

How to capture response error/message in separate route?

I just want to capture the response error from a middleware function, it works if I write the code as follows:
var express = require('express');
var expressValidator = require('express-validator');
var app = express();
var bodyParser = require('body-parser');
var router = require('./routes');
//monk.mongoList();
app.use(bodyParser.urlencoded({extented:true}));
app.use(bodyParser.json());
app.use(expressValidator([]));
var port = process.env.PORT || 8978;
router.get('/',function(req,res,next) {
var error = Error('Article is not found');
next(error.message);
return res.send("Hello World!");
});
app.use(function(err,req,res,next) {
console.log(err + "TET");
})
app.listen(port);
but I want to separate the following code:
app.use(function(err,req,res,next) {
console.log(err + "TET");
})
and use it as follows:
app.js
var express = require('express');
var expressValidator = require('express-validator');
var app = express();
var bodyParser = require('body-parser');
var router = require('./routes');
//monk.mongoList();
app.use(bodyParser.urlencoded({extented:true}));
app.use(bodyParser.json());
app.use(expressValidator([]));
var port = process.env.PORT || 8978;
var test = require('./util/test')
app.use(test.logger);
app.use('/',router);
app.listen(port);
console.log('test node API ' + port );
util/test.js
module.exports.logger = function (err, req, res, next) {
console.log('LOGGED')
next()
}
/routes/index.js EDIT: I just edited the /routes/index.js file to make it more simple
var express = require('express');
var router = express.Router();
var url = require('url');
router.get('/api', function(req, res, next) {
var err = "this is error";
var error = Error (err)
var data = { data: "Succuss"}
if (err) {
next(error.message)
res.json({message:err})
}else {
res.json(data);
}
});
module.exports = router;
When add the above code, nothing appear in the console.

Socket.IO and express routes

I would like to use socket.io and express routes and I have the following code:
app.js
var
http = require('http'),
path = require('path'),
passport = require('passport'),
userpassport = require('./lib/strategies/local'),
githubpassport = require('./lib/strategies/github'),
flash = require('connect-flash'),
express = require('express'),
logger = require('morgan'),
bodyParser = require('body-parser'),
cookieParser = require('cookie-parser'),
session = require('express-session'),
errorhandler = require('errorhandler'),
csrf = require('csurf'),
favicon = require('serve-favicon'),
sockets = require('./lib/socket'),
app = express();
var routes = require('./routes')();
app.get('/', routes.index);
var server = http.createServer(app).listen(app.get('port'), function () {
var io = require('socket.io')(server);
io.on('connection', function (iosocket) {
sockets.setSocket(iosocket);
});
});
lib/socket.js
var socket;
exports.setSocket = function(iosocket) {
console.log('setting socket');
socket = iosocket;
}
exports.getSocket = function() {
console.log('getting socket');
return socket;
}
routes/index.js
var sockets = require('../lib/socket');
module.exports = function () {
var routes = {};
routes.index = function (req, res) {
var socket = sockets.getSocket();
socket.on('app/create', function (data) {
console.log('got app create');
});
}
This does not work, I think it's because the setSocket function that appears on app.js runs after the page was loaded, therefore when I getSocket on the route it's not the latest socket (I can console log the given socket on the route, I can see there's a socket there, but I can also see that the setSocket runs afterwards).
How can I solve this?

Resources