separate logic from view with route - node.js

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();
});
});

Related

Pass data from client to server. Express

i'm little stuck on my express application.
I have a file index.js in routes folder and I want to save the result of mydata
var express = require('express');
var router = express.Router();
router.get('/', token, function(req, res, next) {
var mydata = req.userId
res.render('index', {
title: 'Welcolme',
});
});
module.exports = router;
And, in my other file (which depends on app.js), I would like to get and pass mydata to the server
var app = require('../app');
server.listen(port, function () {
require('../assets/js/server/socket')(server, mydata);
});
(Here is my app.js)
var express = require('express');
var indexRouter = require('./routes/index');
var path = require('path');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'twig');
app.use('/', indexRouter);
module.exports = app;
And the socket file
var io = {};
module.exports = (server, mydata) => {
console.log('Hello : ' , mydata)
io = require('socket.io')(server);
io.on('connection', (socket) => {
console.log('Connected')
});
};
Is there a way to do that?
Thank you :)
Maybe instead of still having this route.get('/') ...
You can let the user enter the data and have it transferred directly through the WebSocket connection.
Example:
//Client-side
//Get the user data somewhere from the HTML page
const userData = document.getElementbyId("some html element's id here").innerHTML;
//Send it to the back end
socket.emit('userData',userData)
//Open a listener to get the data from the back end later
socket.on('processedData',processedData=>{
//Use it in the way you desired.
});
//Server-side
io.on('connection', (socket) => {
console.log('Connected')
socket.on('userData',userData=>{
//Do something here, like validation and stuff
socket.emit('processedData','processedData here')
});
});

Emitting and receiving events with Socket.io

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);

Node js, how to combine Socket.io with mustache

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

Socket.io and Express3 - 404 on client request to /socket.io/socket.io.js

I am receiving a 404 when trying to resolve '/socket.io/socket.io.js' from my Node server. I can't determine why.
My server configuration looks like this:
var express = require('express')
, engine = require('ejs-locals')
, app = express()
, http = require('http')
, server = http.createServer(app)
, io = require('socket.io').listen(server);
// use ejs-locals for all ejs templates:
app.engine('ejs', engine);
app.set('views',__dirname + '/views');
app.set('view engine', 'ejs'); // so you can render('index')
app.use(express.static(__dirname + '/public'));
//define routes
...
app.listen(3000);
//socket io
io.sockets.on('connection', function (socket) {
socket.on('set nickname', function (name) {
socket.set('nickname', name, function () {
socket.emit('ready');
});
});
socket.on('msg', function () {
socket.get('nickname', function (err, name) {
console.log('Chat message by ', name);
});
});
});
At the client I have this:
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost:3000');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
</script>
I am testing this locally (port: 3000). The Socket code is basically ripped off of the socket.io example to get something working. I have reviewed other posts and can't seem to find where I'm going wrong. Can someone help?
Thanks
Got it!
The HTTP server needs to be listing on the port (3000 in this case.) I then removed the app.listen(3000) as the address will already be in use and is not needed.
Thanks!
var express = require('express')
, engine = require('ejs-locals')
, app = express()
, http = require('http')
, server = http.createServer(app).listen(3000)
, io = require('socket.io').listen(server);

Nodejs include socket.io in router page

I have an express node app, and I'm trying to keep my code neat by not having all the socket.io stuff in app.js
I don't know the best way to go about this. Here is my initial thought which doesn't feel like the cleanest one
// app.js
var express = require('express')
, app = express()
, server = require('http').createServer(app)
, url = require('url')
, somePage = require('./routes/somePage.js')
, path = require('path');
app.configure(function(){...});
app.get('/', somePage.index);
and the route
// somePage.js
exports.index = function (req, res, server) {
io = require('socket.io').listern(server)
res.render('index',{title: 'Chat Room'})
io.sockets.on('connection', function(socket) {
...code...
}
}
I feel like I'm close but not quite there
I don't know if I'm reading that right but it looks like you are starting a socket server on every request for /, which I'm frankly a little surprised works at all.
This is how I'm separating out the socket.io code from app.js (using express 3.x which is a bit different than 2.x):
// app.js
var express = require('express');
var app = express();
var server_port = config.get('SERVER_PORT');
server = http.createServer(app).listen(server_port, function () {
var addr = server.address();
console.log('Express server listening on http://' + addr.address + ':' + addr.port);
});
var sockets = require('./sockets');
sockets.socketServer(app, server);
// sockets.js
var socketio = require('socket.io');
exports.socketServer = function (app, server) {
var io = socketio.listen(server);
io.sockets.on('connection', function (socket) {
...
});
};
Hope that helps!
a similar approach is to pass app into index.js file and initiate http and socketio server there.
//app.js
//regular expressjs configuration stuff
require('./routes/index')(app); //all the app.get should go into index.js
Since app is passed into index.js file, we can do the app.get() routing stuff inside index.js, as well as connecting socketio
//index.js
module.exports = function(app){
var server = require('http').createServer(app)
,io = require('socket.io').listen(server);
app.get('/', function(req, res){
});
server.listen(app.get('port'), function(){
console.log("Express server listening on port " + app.get('port'));
});
io.sockets.on('connection', function(socket){
socket.on('my event', function(data){
console.log(data);
});
});
io.set('log level',1);
//io.sockets.emit(...)

Resources