My app.js
const express = require('express'),
morgan = require('morgan'),
bodyParser = require('body-parser'),
path = require('path'),
mongoose = require('mongoose'),
app = express(),
config = require('./config'),
Note = require('./models/note'),
server = require('http').createServer(app),
io = require('socket.io')(server),
socket = io.socket;
mongoose.connect('mongodb://'+config.db.host+'/'+config.db.name);
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// Serve static assets
app.use(express.static(path.resolve(__dirname, '..', 'build')));
app.use(function(req, res, next) {
const allowedOrigins = [
'http://127.0.0.1:8000',
'http://localhost:8000',
'http://127.0.0.1:3000',
'http://localhost:3000'];
const origin = req.headers.origin;
if(allowedOrigins.indexOf(origin) > -1){
res.setHeader('Access-Control-Allow-Origin', origin);
}
//res.header("Access-Control-Allow-Origin", "127.0.0.1 localhost");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header('Access-Control-Allow-Credentials', true);
next();
});
calling socket.emit() in handlers after above codes.
My index.js
'use strict';
const app = require('./app'),
// server = http.createServer(app),
PORT = process.env.PORT || 8000;
app.listen(PORT, () => {
console.log(`REST API running on ${PORT}!`);
});
Console output:
Any idea? Thanks
If you're going to do this:
server = require('http').createServer(app),
Then, you can't do:
app.listen(PORT, ...);
because app.listen() will create a new and different server and socket.io will not be associated with that one.
Instead, you need to do:
server.listen(PORT, ...)
using the server value from app.js. And, if you want to require() in the server from app.js, you also need to export it from app.js (something else I don't see your code doing).
For reference, the code for app.listen(), does this:
app.listen = function listen() {
var server = http.createServer(this);
return server.listen.apply(server, arguments);
};
You can see how it creates a different server than the one you passed to socket.io. Thus the one you passed to socket.io is never started and thus socket.io does not work.
Related
i'm trying to add socket.io on my already existing NodeJS API REST Project.
var express = require('express')
var bodyParser = require('body-parser');
var https = require('https');
var http = require('http');
var fs = require('fs');
var router = require('./route/router');
require('dotenv').config();
var app = express();
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(require('helmet')());
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Authorization,Content-Type');
next();
});
router(app);
if (process.env.PRODUCTION === "false") {
http.createServer(app).listen(8080, function() {
console.log('8080 ok');
});
var io = require('socket.io')(http);
} else {
const options = {
cert: fs.readFileSync('./../../etc/letsencrypt/live/test.com/fullchain.pem'),
key: fs.readFileSync('./../../etc/letsencrypt/live/test.com/privkey.pem')
};
https.createServer(options, app).listen(8443, function() {
console.log('8443 ok');
});
var io = require('socket.io')(https);
}
io.sockets.on('connection', socket => {
console.log('socketio connected');
});
I have no error displayed (server side). But, when I tried on client side, this.socket = io('ws://localhost:8080/');, it's not working at all.
I get GEThttp://localhost:8080/socket.io/?EIO=3&transport=polling&t=NG6_U6i [HTTP/1.1 404 Not Found 1ms] browser console.
It seems that something is not ok with the server, but I can't find what's going on
Any idea ?
Thanks
Try this way, you need to include (I don't know if this is the correct word to use) the express server into the socket.io server.
const express = require('express');
const socketio = require('socket.io');
const port = process.env.PORT || 3006;
const app = express();
const server = app.listen(port, () => {
console.log(`App started on port ${port}`)
});
const io = socketio(server, { forceNew: true });
io.on('connect', (socket) => {
// do this
// do that
});
The code above is a skeleton of how express and socket.io are used together. Please modify it as per your needs.
Good luck.
I've been working on chat functionality for my website hosted on Azure app service. I'm using the socket on port 443 as app service won't allow any other port than 80 and 443.
Socket functionality works fine on localhost but this error shows up when I deploy:
websocket.js:122 WebSocket connection to 'wss://mydomain/socket.io/?EIO=3&transport=websocket' failed: Error during WebSocket handshake: Unexpected response code: 500
this is I'm connecting on client-side:
const socket = io.connect("https://mydomain:443", {transports: ['websocket'], secure: true, port: '443'});
This is my server.js file
const express = require("express");
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const passport = require("passport");
const users = require("./routes/api/users");
const base = require("./routes/api/base");
const leads = require("./routes/api/leads");
const requests = require("./routes/api/requests");
const offApp = require("./routes/api/offApp");
const chat = require("./routes/api/chat");
const chatSocket = require("./routes/socket/chat");
const path = require("path"); // on top
const app = express();
const cors = require('cors')
const https = require('https');
const fs = require('fs');
/**
* App.
*/
const privateKey = fs.readFileSync('private.key').toString();
const certificate = fs.readFileSync('certificate.crt').toString();
const ca = fs.readFileSync('ca_bundle.crt').toString();
const server = https.createServer({key:privateKey,cert:certificate,ca:ca }, app);
const client = require('socket.io').listen(server);
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*"); // update to match the domain you will make the request from
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
client.origins('*:*');
client.set('transports', ['websocket']);
server.listen(443);
// Bodyparser middleware
app.use(
bodyParser.urlencoded({
extended: false
})
);
app.use(bodyParser.json());
// DB Config
const db = require("./config/keys").mongoURI;
// Connect to MongoDB
mongoose
.connect(
db,
{ useNewUrlParser: true }, (err, db) => {
if (err) {
throw err;
}
console.log('MongoDB connected');
chatSocket(db, client);
});
// Passport middleware
app.use(passport.initialize());
// Passport config
require("./config/passport")(passport);
// Routes
app.use("/api/users", users);
app.use("/api/base", base);
app.use("/api/leads", leads);
app.use("/api/requests", requests);
app.use("/api/offapp", offApp);
app.use("/api/chat", chat);
const port = process.env.PORT || 5000;
app.use(express.static("client/build")); // change this if your dir structure is different
app.get("*", (req, res) => {
res.sendFile(path.resolve(__dirname, "client", "build", "index.html"));
});
app.listen(port, () => console.log(`Server up and running on port ${port} !`));
I haven't found any error in logs
I was able to solve this problem by using the default port. (Not the best solution but for Azure App service I couldn't find any other solution)
For the client-side I am connecting to socket like this.
const socket = io.connect("https://example.com", {transports: ['websocket'], secure: true});
And this is how my server-side looks like.
const express = require("express");
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const passport = require("passport");
const users = require("./routes/api/users");
const base = require("./routes/api/base");
const leads = require("./routes/api/leads");
const requests = require("./routes/api/requests");
const offApp = require("./routes/api/offApp");
const chat = require("./routes/api/chat");
const chatSocket = require("./routes/socket/chat");
const path = require("path"); // on top
const app = express();
const cors = require('cors')
const https = require('https');
const fs = require('fs');
/**
* App.
*/
var privateKey = fs.readFileSync('private.key').toString();
var certificate = fs.readFileSync('certificate.crt').toString();
var ca = fs.readFileSync('ca_bundle.crt').toString();
// var server = https.createServer({key:privateKey,cert:certificate,ca:ca }, app);
var server = require('http').createServer(app);
var client = require('socket.io').listen(server);
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*"); // update to match the domain you will make the request from
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
client.origins('*:*');
client.set('transports', ['websocket']);
// Bodyparser middleware
app.use(
bodyParser.urlencoded({
extended: false
})
);
app.use(bodyParser.json());
// DB Config
const db = require("./config/keys").mongoURI;
// Connect to MongoDB
mongoose
.connect(
db,
{ useNewUrlParser: true }, (err, db) => {
if (err) {
throw err;
}
console.log('MongoDB connected');
chatSocket(db, client);
});
// Passport middleware
app.use(passport.initialize());
// Passport config
require("./config/passport")(passport);
// Routes
app.use("/api/users", users);
app.use("/api/base", base);
app.use("/api/leads", leads);
app.use("/api/requests", requests);
app.use("/api/offapp", offApp);
app.use("/api/chat", chat);
const port = process.env.PORT || 5000;
app.use(express.static("client/build"));
app.get("*", (req, res) => {
res.sendFile(path.resolve(__dirname, "client", "build", "index.html"));
});
server.listen(port);
I have a node & express app that is currently hosted on a shared hosting. I would like to run and manage the app using Phusion Passenger. My hosting account supports nodejs applications managed by Passenger which i have never used before.
The server code generated when setting up the Node app is the basic server setup as below.
var http = require('http');
var server = http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
var message = 'It works!\n',
version = 'NodeJS ' + process.versions.node + '\n',
response = [message, version].join('\n');
res.end(response);
});
server.listen();
I would like to replace this with the code below that has elements of express that i am using to serve my API routes.
//import modules
var express = require('express'),
bodyParser = require('body-parser'),
morgan = require('morgan'),
cors = require('cors');
path = require('path');
var app = express();
var port = process.env.PORT || 3000;
//import database connection from dbconnect.js file
var mysql = require('./dbconnect/dbconnect');
//Parse as urlencoded and json.
app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());
//adding middleware - cors
app.use(cors());
//Http logger
app.use(morgan('dev'));
//Uncomment for production
//app.use(express.static(__dirname + '/public'));
// Point static path to public
app.use(express.static(path.join(__dirname, 'public')));
//import routes from /routes/routes.js
var user = require('./routes/Users');
route = require('./routes/route');
router = require('./router/router');
//adding routes
app.use('/api', user, route, router);
// Catch all other routes and return the index file
app.get('/*', (req, res) => { res.sendFile(path.join(__dirname, '/public/index.html'));
});
app.use(function (req,res,next){
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "x-access-token, Origin, Content-Type, Accept");
next();
});
app.listen(port, function() {console.log('Server started at http://localhost:'+port+'/');});
but i get the error:
I am currently running my server script on the shared server using Forever, which is working fine but that hasn't been efficient, so i would like to switch to using Passenger.
Are you able to set your NODE_ENV=development and then look at your page again? It will likely output a lot more information, why it throws the Error.
With the error information, we can have a better look at what might be wrong.
Thanks,
Marc
I suspect it has to do with your routes and it not finding the files.
So, I have the simple dream to start the Server with Socket.io library, but for some reasons it's does not happen... I cannot understand what is wrong, because I do not gets even the standart message on server run - Server running on port ${port}.
Help, please...
'use strict'
const express = require('express');
const http = require('http');
const io = require('socket.io');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const bcrypt = require('bcrypt-nodejs');
const session = require('express-session');
const MongoStore = require('connect-mongo')(session);
const app = express();
const server = http.Server(app);
const socketServer = io(server);
const router = express.Router();
const chat = require('./routes/chat');
const profile = require('./routes/profile');
const registration = require('./routes/registration');
const login = require('./routes/login');
const logout = require('./routes/logout');
const EmployersSchemaDB = require('./SchemaDB/EmployersSchemaDB');
const MessagesSchemaDB = require('./SchemaDB/MessagesSchemaDB');
const User = require('./SchemaDB/ShemaAuthtificaion');
mongoose.connect('mongodb://test_db');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(cookieParser());
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
res.setHeader('Access-Control-Allow-Credentials', 'true');
res.setHeader('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers');
res.setHeader('Cache-Control', 'no-cache');
next();
});
app.use(session({
secret: 'work hard',
resave: true,
saveUninitialized: false,
store: new MongoStore({ mongooseConnection: mongoose.connection })
}));
router.route('/')
.get((req, res) => {
res.json('Hello on the Homepage!');
});
app.use('/', router);
app.use('/chat', chat);
app.use('/profile', profile);
app.use('/auth/login', login);
app.use('/auth/logout', logout);
app.use('/auth/registration', registration);
const port = process.env.API_PORT || 8989;
socketServer.listen(port, () => {
console.log(`Server running on port ${port}`);
});
Change from this:
socketServer.listen(port, () => {
console.log(`Server running on port ${port}`);
});
to this:
server.listen(port, () => {
console.log(`Server running on port ${port}`);
});
You need to start your http server. That's the core server here that works with both Express and socket.io and fields all incoming requests.
Your variable socketServer and your io variable are misnamed (which is probably part of your confusion). socketServer is the actual server, that's the socket.io server-side instance which is typically named io. See the socket.io server doc for details.
You should start with a simpler server:
const express = require('express');
const socketio = require('socket.io');
const http = require('http');
const app = express();
const server = http.createServer(app);
const socket = socketio(server);
app.use(express.static(`./public`));
socket.on('connect', socket => {
socket.emit('identify', {'server':'server data'});
});
socket.on('data', data => {
console.log(data);
});
server.listen(4000, () => {
console.log('Server up and running on port 4000');
});
In the front end you can test this like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test</title>
</head>
<body>test
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.1.1/socket.io.js"></script>
<script type="text/javascript">
'use strict';
var socket = io('http://localhost:4000');
socket.on('identify', function (socket) {
console.log(socket);
});
</script>
</body>
</html>
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");
};