I'm trying to emit an event with socket.io on my Node Js server and receive it client-side but I can't get it to work.
This is my server code:
// require our dependencies
var express = require('express');
var expressLayouts = require('express-ejs-layouts');
var bodyParser = require('body-parser');
var app = express();
var port = 3000;
var server = require("http").Server(app);
var io = require('socket.io')(server);
// use ejs and express layouts
app.set('view engine', 'ejs');
app.use(expressLayouts);
// use body parser
app.use(bodyParser.json({extended : true}));
// route our app
var router = require('./app/routes');
app.use('/', router);
// set static files (css and images, etc) location
app.use(express.static(__dirname + '/public'));
// start the server
app.listen(port, function() {
console.log('app started');
});
This is my routes.js code, where the magic should happen:
module.exports = function(io){
// require express
var express = require('express');
var path = require('path');
// create our router object
var router = express.Router();
// export our router
//module.exports = router;
router.post("/", function(request, response) {
console.log(request.body);
io.emit('getupdate',{hello:'world'});
});
// route for our homepage
router.get('/showevent', function(req, res) {
res.render('pages/showevent',{data:exportage});
});
return router;
}
While this is my client-side script:
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost:3000');
socket.on('getupdate', function (data) {
console.log(data);
});
</script>
On the routes.js file, to get the "io" variable i wrapped all inside a function.
I can't get the message emitted in case of a POST request on my client.
Could you help me to find the issue here ?
Try this:
// require our dependencies
var express = require('express');
var expressLayouts = require('express-ejs-layouts');
var bodyParser = require('body-parser');
var app = express();
var port = 3000;
var server = app.listen(port);
var io = require('socket.io').listen(server);
I am not sure if you have updated this in your own code, but this snippet should pass io to the router:
// route our app
var router = require('./app/routes')(io);
app.use('/', router);
Related
I have a small project with NodeJS Express server and Angular2 frontend. The server has an API interfaces. The main part of this is: /api/alert. I want to do the following: If the /api/alert get an request then socket.io broadcast an event to all connected clients.
My server structure is the following:
server.js
var http = require('http'),
express = require('express'),
app = module.exports.app = express(),
port = process.env.PORT || 3000,
mongoose = require('mongoose'),
bodyParser = require('body-parser'),
db = require('./config/db'),
path = require('path');
mongoose.Promise = global.Promise;
mongoose.connect(db.url);
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, 'dist')));
var routes = require('./server/routes/index');
routes(app);
var server = http.createServer(app);
var io = require('socket.io')(server);
server.listen(port);
console.log('Server started on: ' + port);
server/routes/index.js
const deviceRoute = require('./devicesRoute');
const alertRoute = require('./alertsRoute');
module.exports = function(app) {
deviceRoute(app);
alertRoute(app);
}
server/routes/alertRoute.js
'use strict';
module.exports = function(app) {
var alertsService = require('../services/alertsService');
app.route('/api/alert')
.post(alertsService.createAlert);
};
server/service/alertService.js
'use strict';
exports.createAlert = function(req, res) {
// do something in database
// I want to broadcast to all client HERE
};
I can't pass the io and server variables to the function (from server.js). How can I do that? What is the easiest way?
Thank you!
First you would want to export both the app and server objects from server.js and pass your socket to your response in middleware as follows:
var app = express();
var server = http.createServer(app);
var io = require('socket.io')(server);
app.use(function(req, res, next){
res.io = io;
next();
});
...
module.exports = {app: app, server: server};
You can then require the server instance you created in server.js (depending on where you are requiring it from) as
var server = require('../server').server;
Since you added socket.io to the response object, you can use it in your services as
'use strict';
exports.createAlert = function(req, res) {
// do something in database
// I want to broadcast to all client HERE
res.io.emit("broadcast", "clients");
};
I am working on making adjustments to teammates code and I haven't been able to understand how they have done their routing. I am attempting to have Express run a middleware script when an end-user goes to a new session of the web application.
I don't know what to test next to figure out how they have done their routing.
Main.js
// Dependencies
var http = require('http');
var express = require('express');
var path = require('path');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var busboy = require('connect-busboy');
var cors = require('cors');
var mongoose = require('mongoose');
// Configuration
var config = require('./config');
var twilio = require('twilio');
// Database
mongoose.connect(config.database);
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function(){
console.log('Connected to database');
});
var app = express();
app.set('port', process.env.PORT || 3000);
// Setup middleware
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cookieParser(config.sessionSecret));
app.use(express.static(path.join(__dirname, 'dist')));
app.use(busboy());
app.use(cors({
origin: true,
credentials: true
}));
app.all('/*',function(req,res){
twilio.notifyOnSession();
console.log('Message Sent');
})
var server = http.createServer(app);
var port = app.get('port');
server.listen(port);
console.log('Listening on port ' + port);
// Load server router
require('./router')(app);
/router/index.js
var path = require('path');
module.exports = function(app){
console.log('Initializing server routing');
require('./auth')(app);
require('./api')(app);
// Determine if incoming request is a static asset
var isStaticReq = function(req){
return ['/auth', '/api', '/js', '/css'].some(function(whitelist){
return req.url.substr(0, whitelist.length) === whitelist;
});
};
// Single page app routing
app.use(function(req, res, next){
if (isStaticReq(req)){
return next();
}
res.sendFile(path.join(__dirname, '../dist/index.html'));
});
};
Your app.all('/*' is swallowing all requests before they can hit your router.
Don't do that.
I was able to resolve the issue by creating a new route with twilio.js and having the router look for the url twilio/new. Thanks all for the help.
This is the picture of my server
https://drive.google.com/file/d/1GA57RyYsc5ik1pSlLhAGtgGjbp_vLFoH/view?usp=sharing
When I go to http://localhost:3000/
I get the error message: Cannot Get/
myserver.js
// TODO: mount the tigers route with a a new router just for tigers
// exactly like lions below
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var _ = require('lodash');
var morgan = require('morgan');
var lionRouter = require('./lions');
var tigerRouter = require('./tigers');
app.use(morgan('dev'))
app.use(express.static('client'));
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
// this is called mounting. when ever a req comes in for
// '/lion' we want to use this router
app.use('/lions', lionRouter);
app.use(function(err, req, res, next) {
if (err) {
res.status(500).send(error);
}
});
app.listen(3000);
console.log('on port 3000');
Whenever you are trying to visit any url on the browser , then browser makes a GET request to that url, in your case you are not sending any response on the url: "http://localhost:3000/. You can try something like this.
app.route('/*')
.get(function(req, res) {
res.sendFile(path.resolve("./client") + '/index.html'));
});
Check the naming you used, it shows myserver.js instead of server.js as in the picture you uploaded.
Check your routing on line 10 of you code
var lionRouter = require('./lions');
var tigerRouter = require('./tigers');
. try this edited codes
server.js
// TODO: mount the tigers route with a a new router just for tigers
// exactly like lions below
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var _ = require('lodash');
var morgan = require('morgan');
var lionRouter = require('./server/lions');
var tigerRouter = require('./server/tigers');
app.use(morgan('dev'))
app.use(express.static('client'));
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
// this is called mounting. when ever a req comes in for
// '/lion' we want to use this router
app.use('/lions', lionRouter);
app.use(function(err, req, res, next) {
if (err) {
res.status(500).send(error);
}
});
app.listen(3000);
console.log('on port 3000');
Express static directory is given client but it is present on parent directory.
So i have resolve this issue with path module and now this will work for you.
// TODO: mount the tigers route with a a new router just for tigers
// exactly like lions below
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var _ = require('lodash');
var morgan = require('morgan');
var path = require('path')
var lionRouter = require('./lions');
var tigerRouter = require('./tigers');
app.use(morgan('dev'))
app.use(express.static(path.join(__dirname, '../client')));
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
// this is called mounting. when ever a req comes in for
// '/lion' we want to use this router
app.use('/lions', lionRouter);
app.use(function(err, req, res, next) {
if (err) {
res.status(500).send(error);
}
});
app.listen(3000);
console.log('on port 3000');
Your code works fine after commenting the following three lines of your code:
var lionRouter = require('./lions');
var tigerRouter = require('./tigers');
app.use('/lions', lionRouter);
Check if any error is present in LionsJS.
Socket.io can be used in the general html page, but it can not be used in the mustache page?
For example:
app.js
var app = express();
app.use(express.static(path.join(__dirname, 'public')));
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'mustache'); // name your templates
app.engine('mustache', require('hogan-middleware').__express);
var routes = require('./routes/index');
app.use('/', routes);
routes\index.js
var express = require('express');
var router = express.Router();
var app = express();
var server = require('http').Server(app);
var io = require('socket.io').listen(server);
var request = require('request');
var serialport = require('serialport');
var Serialport = serialport;
router.get('/machine_mode', function(req, res, next) {
res.render('machine_mode', { title: 'test' });
});
io.sockets.on('connection',function(socket){
var str='hello';
io.sockets.emit('view',str);
});
views\test.mustache
<body>
</body>
<script src="/js/jquery-1.9.1.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
jQuery(function($){
var socket = io.connect();
socket.on('str',function(data){
})
});
the test page error:
can not GET
http://localhost:8001/socket.io/socket.io.js
app.js
var express = require('express');
var router = express.Router();
var app = express(); // Brackets Missing
var server = require('http').createServer(app); // Need to do like this
var io = require('socket.io').(server); // Need to pass server
var request = require('request');
var serialport = require('serialport');
var Serialport = serialport;
router.get('/machine_mode', function(req, res, next) {
res.render('machine_mode', { title: 'test' });
});
io.on('connection',function(socket){ // io.socket is not required
var str='hello';
sockets.emit('view',str);
});
I'm pretty new to Node and I'm using express.
I'm trying to implement simple file explorer.
enough talking here's some code:
(root dir is /app for this ex.)
my app.js:
var express = require('express');
var fs = require('fs');
var path = require('path');
var ejs = require('ejs');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io').listen(server);
var explorer = require('./routes/explorer');
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use("/public", express.static(__dirname + '/public'));
app.use('/', explorer);
server.listen(3000,function(){
console.log('Server started on http://localhost:3000');
});
io.on('connection',function(client){
console.log('connection with io established');
});
module.exports.app = app;
module.exports.server = server;
see that I have routing '/' to explorer
and the explorer.js:
var express = require('express');
var router = express.Router();
var fs = require('fs');
router.get('/', function(req, res, next) {
res.render('explorer',{
currentPath : currentPath
});
});
function getUserHome() {
var rawPath = process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME'];
return rawPath;
}
function clicked(){
console.log(getUserHome());
}
the view explorer.ejs:
<div class="clickable">clickme</div>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost:3000');
$('.clickable').click(function(){
socket.emit('clicked');
});
</script>
basically i want to catch the "clicked" emit from the view and trigger the clicked function in the explorer.js. in other words i want the view and the explorer.js talk by socket.io, so the view can talk with the file system.
i tried few way and got bunch of error.
thank you so much!
So you've triggered the event 'clicked' on your client side :
// Client side :
var socket = io.connect('http://localhost:3000');
$('.clickable').click(function(){
socket.emit('clicked');
});
Now, you have to catch it on the server side, in the explorer.js file :
// Server side :
// Instanciate your socket.io on the server side
var io = require('socket.io')(server)
// Listen for a client connection :
io.sockets.on('connection', function(socket){
// Inside the connection, you can now declare each function for each event triggered on the client side
socket.on('clicked', function() {
// This is your callback,
//+ the code in this scope will be executed
//+ only when the event 'clicked' is emitted
cliked();
});
});