Node use socket.io with ejs and router - node.js

I tried to get socket.io to run, but I always get a client error, so I think there is a logic bomb inside the code.
app.js
const express = require('express');
const app = express();
const router = express.Router();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.set('socketio', io);
const expressLayouts = require('express-ejs-layouts');
module.exports = router;
app.use(express.static(__dirname));
app.use(express.urlencoded({ extended: true }));
app.use(expressLayouts);
app.set('view engine', 'ejs');
app.use(function(req, res, next) {
next();
});
io.on('connection', function(socket){
console.log('a user connected');
});
app.use('/', require('./routes/test.js'));
const PORT = process.env.PORT || 8081;
app.listen(PORT, console.log(`Server started on port ${PORT}`));
Inside the route file I open the page
test.js
const express = require('express');
const router = express.Router();
// Dashboard
router.get('/start', (req, res, next) => {
res.render('index2', {
caseArray: 'eins'
});
});
module.exports = router;
And finally inside the template I added:
<script
src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
crossorigin="anonymous"
></script>
<script src="/socket.io/socket.io.js"></script>
<script>var socket = io();</script>
But I always get an error message inside the browser console:
GET http://localhost:8081/socket.io/socket.io.js net::ERR_ABORTED 404 (Not Found)
(index):24 Uncaught ReferenceError: io is not defined
at (index):24
As I understand from all the tutorial is, that node will send the socket.io within the request to the html page and that with the html page the server get connected. But there is no connection message because the files do not exists. Where is my problem? In client or server?

It seems node is trying to locate socket.io's js files on your server on the route /socket/socket.io.js which I assume you haven't defined
I would suggest you use Socket io's cdn link and place it between your html header tags
<script src='https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.1.1/socket.io.js'></script>

For all with a similar problem. I solved it by using
server.listen(PORT, console.log(`Server started on port ${PORT}`));
instead of using
app.listen(PORT, console.log(`Server started on port ${PORT}`));

Related

Cannot connect socket.io with backend using react

I am newbie and starting learning socket.io. I created my backend with express-generator, I installed all required dependencies and the server working fine with no error, however, when I try to connect socket.io from frontend in React it gives many errors and I am not able to connect to connect, I have seen all the question and answer but cannot fix it, all code is given below.
info: I have exported server from bin/www file, and import it in app.js in backend and all modules version are latest
var server = http.createServer(app);
exports.server = server;
"Express Server"
var createError = require("http-errors");
var express = require("express");
var path = require("path");
var cookieParser = require("cookie-parser");
var logger = require("morgan");
var cors = require("cors");
const { server } = require("./bin/www");
var io = require("socket.io")(server);
var indexRouter = require("./routes/index");
var usersRouter = require("./routes/users");
var app = express();
// view engine setup
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "jade");
app.use(cors());
app.use(logger("dev"));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, "public")));
// Socket.io config
io.on("connection", (socket) => {
console.log("Connected");
});
app.use("/", indexRouter);
app.use("/users", usersRouter);
// catch 404 and forward to error handler
app.use(function (req, res, next) {
next(createError(404));
});
// error handler
app.use(function (err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get("env") === "development" ? err : {};
// render the error page
res.status(err.status || 500);
res.render("error");
});
module.exports = app;
"React"
import React from "react";
import socket from "socket.io-client";
import "./App.css";
const ENDPOINT = "http://localhost:3000";
function App() {
const io = socket(ENDPOINT);
return (
<div className="App">
<h1>Working</h1>
</div>
);
}
export default App;
Logs in backend
GET /socket.io/?EIO=4&transport=polling&t=NRtAs89 404 14.138 ms - 1362
GET /socket.io/?EIO=4&transport=polling&t=NRtAsNq 404 8.662 ms - 1362
GET /socket.io/?EIO=4&transport=polling&t=NRtAtc3 404 10.450 ms - 1362
GET /socket.io/?EIO=4&transport=polling&t=NRtAtrY 404 15.608 ms - 1362
GET /socket.io/?EIO=4&transport=polling&t=NRtAv3j 404 13.641 ms - 1362
GET /socket.io/?EIO=4&transport=polling&t=NRtAvJH 404 10.490 ms - 1362
Logs in console frontend
The server is not listening for any incoming connection. You didn't start the server as far as I can tell from your code. That's why the frontend is giving you a 404 not found. You have to call .listen()
I am putting everything in one file for simplicity's sake. You can separate them later one for your file in /bin/www/
const express = require('express');
// Initialize the app
const app = express();
// Initialize socket.io server
const server = require('http').createServer(app);
const io = require('socket.io')(server);
PORT = 3003
// Start the Server (socket.io + express)
server.listen(PORT, () => {
console.log(`Server is listening on port ${PORT}`);
});
Update:
If you want to bind socket.io with express, you will have to bind it before you call .listen() Otherwise, socket.io won't start.
Just tested with express-generator myself. You will need to move the socket.io logic into /bin/www. Like the following:
const server = require('http').createServer(app);
const io = require('socket.io')(server);
Side Note:
Personally, I suggest you not to use express-generator if you are going to combine it with socket.io. express-generator gives you a rigid boilerplate that undoubtedly includes lots of things that are irrelevant to your app. Plus the template is still using var to assign variables. ES6 has been out there for 6 years already.

Deploying mongo from local to server

I am trying to connect to an API that I have up and running on my local machine but I can't access on my production server.
It's running on node.js with mongoose and I have set up the server to listen on port 3000.
When I test in postman:
http://178.128.37.170:3000/
I get the following response:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<>Cannot GET /</>
</body>
</html>
I have created a 'Hello world' response in the router:
app.get('/', (req, res) => res.send('Hello World!'))
I am not sure where this is getting blocked, if it is a port, firewall or IP issue or something else.
I have disabled both Apache and SSL in case they were interfering.
Here is my server.js file:
var express = require('express'),
cors = require('cors'),
app = express(),
port = process.env.PORT || 3000,
mongoose = require('mongoose'),
Supporter = require('./api/models/todoListModel'), //created model loading here
bodyParser = require('body-parser'),
helmet = require('helmet');
// Test SSL connection
var MongoClient = require('mongodb').MongoClient;
// mongoose instance connection url connection
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://localhost/Tododb'); // was tododb
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(helmet());
app.use(cors());
app.get('/task/', function (req, res, next) {
res.json({msg: 'This is CORS-enabled for all origins!'})
})
var routes = require('./api/routes/todoListRoutes');
routes(app); //register the route
app.listen(port);
console.log('Supporter RESTful API server started on: ' + port);
What should I try next?
I fixed this. Somehow, my Mongo database had been deleted from my server but that's another story!
In my server.js, I added this:
app.get('/', (req, res) => res.send('Hello World!'))
That allowed me to work out that express was serving the endpoint.
Then I rang mongo and recreated the database, and eventually got to the routes working.

NodeJS express auto created app binding to server

I created an express app in NodeJS using express --view=pug expressapp. It created an app.js file
app.js
var createError = require('http-errors');
...
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
//socket setup
var socket = require('socket.io');
var io = socket(app);
io.on('connection', function(socket) {
console.log('made socket connection')
})
module.exports = app;
at the end I try to bind socket.io to app but it expects to bind to server like so
var server = app.listen(3000, function() {
});
//socket setup
var socket = require('socket.io');
var io = socket(server);
I also use nodemon so I run the app using nodemon expressapp and it runs on port 3000. However I can't find where the auto generated express files have setup the server. Because If i try like this
//socket setup
var socket = require('socket.io');
var server = app.listen(3000, function() {
});
var io = socket(server);
I get an error that port 3000 is already in use (by itself) I changed it to 4000 and it works.
Not ideal, if you know how to connect with port 3000 will appreciate the assist.
You shall find it under the directory bin/www

Node express server isn't working - how to create and start a server?

I am trying to create and start a server and I've been looking at other code and can't see why mine isn't working (just getting this: localhost just keeps loading and loading and nothing happens).
Any ideas? Thanks!!!
app/server/app.js :
'use strict'
var express= require ('express');
var path=require('path');
var bodyParser = require('body-parser');
var http = require('http');
var app= express();
module.exports = app;
app.use(express.static(path.join(__dirname, '../browser')));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
var server = http.createServer();
server.listen(1337, function () {
console.log('Server is listening on port 1337!');
});
app.use(function (err, req, res, next) {
console.error(err.stack);
res.status(500).send(err.message);
});
app/browser/index.html :
<!DOCTYPE html>
<html lang="en">
<head>
<title>node</title>
</head>
<body>
<div>
<p>Hey whats up</p>
</div>
</body>
</html>
Your code works for me.
The only thing wrong in your code is you have to change server.listen(1337, function ()..., to app.listen(1337, function () {...
Also, I added a file path...
app.get('/', function(req, res){
res.sendFile(path.join(__dirname, '/index.html'));})
...to link your localhost:1337 to your index.html file. Now your index.html file will display when you go to localhost:1337.
Lastly, I'm not sure if you need this line... var server = http.createServer();. I deleted it and everything worked fine.
Here's the code below.
'use strict'
var express= require ('express');
var path=require('path');
var bodyParser = require('body-parser');
var http = require('http');
var app= express();
module.exports = app;
app.use(express.static(path.join(__dirname, '../browser')));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.get('/', function(req, res){
res.sendFile(path.join(__dirname, '/index.html'));
})
app.listen(1337, function () {
console.log('Server is listening on port 1337!');
});
app.use(function (err, req, res, next) {
console.error(err.stack);
res.status(500).send(err.message);
});
Maybe the port You wrote - 1337 is busy, check by choosing other port, for example 4200, or 3000 - server.listen(4200,function () {

Node js with express and socket.io - cannot find socket.io.js

I was working on a node js application with socket.io. I looked at some of the answers on SO but they could not help me with my problem. The error I am getting is
Failed to load resource: the server responded with a status of 404 (Not Found)
localhost/:10 Uncaught ReferenceError: io is not defined
Here is my directory structure:
Judgement
|----node_modules
|----|----express
|----|----socket.io
|----public
|----|----css
|----|----|----judgementMain.css
|----|----js
|----|----|----form.js
|----|----index.html
|----server.js
|----package.json
In my index.html page
I have the following link to socket.io.js
<script type="text/javascript" src="socket.io/socket.io.js"></script>
<script type="text/javascript">
var socket = io();
</script>
<script type="text/javascript" src="js/form.js"></script>
The contents of server.js are as follows
var express = require('express');
var app = express();
var path = require('path');
// Define the port to run on
app.set('port', 3000);
app.use(express.static(path.join(__dirname, 'public')));
// Listen for requests
var server = app.listen(app.get('port'), function() {
var port = server.address().port;
console.log('Magic happens on port ' + port);
});
var http = require('http').Server(app);
var io = require('socket.io')(http);
io.on('connection', function (socket) {
console.log('A user connected');
socket.on('disconnect', function() {
console.log('A user disconnected');
});
});
Can someone explain what I am doing wrong? I only just started with node js and express and socket.io, so any help is appreciated.
Thanks
I see a couple issues:
First, in your HTML, it should be src="/socket.io/socket.io.js" with the leading slash.
Second, you are creating two http servers but only actually starting one of them, when you should be using just one. Your socket.io stuff doesn't work because you're giving it an http server that you never started.
Change to this where you are giving socket.io the http server that express is using and that has been started on your desired port:
var express = require('express');
var app = express();
var path = require('path');
// Define the port to run on
app.set('port', 3000);
app.use(express.static(path.join(__dirname, 'public')));
// Listen for requests
var server = app.listen(app.get('port'), function() {
var port = server.address().port;
console.log('Magic happens on port ' + port);
});
var io = require('socket.io')(server);
io.on('connection', function (socket) {
console.log('A user connected');
socket.on('disconnect', function() {
console.log('A user disconnected');
});
});

Resources