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
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
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);
})
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.
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.
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?