Cannot start NodeJS Server with Socket.io - node.js

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>

Related

Issue to add socketio to API Express

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.

Socket.io + node JS = Error during handshake: error code 500

I was working on Socket.io and node jS to develop a chat web app. It worked locally but I have faced many issues when I deployed my changes to Azure app service.
I am creating a secure connection on port 443. I have resolved other issues but I can't resolve this one.
This the error I'm getting in console on client side.
WebSocket connection to 'wss://mydomain/socket.io/?EIO=3&transport=websocket' failed: Error during WebSocket handshake: Unexpected response code: 500
This is how I'm connecting on server side
var socket = io.connect("https://mydomain:443", {transports: ['websocket'], secure: true, port: '443'});
and this is my server.js code:
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');
var options = {
pfx: fs.readFileSync('certificate.pfx'),
passphrase: 'password'
};
app.use(cors());
var server = https.createServer(options, app);
var client = require("socket.io").listen(server);
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 have checked the logs, there are no errors there.

Socket.io + nodejs = Error during WebSocket handshake: Unexpected response code: 500

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

my app have a problem after i refresh the page

when i open my app for the first time it work just fine but when i refresh the page it give me a url to my index.html file ( /client/build/index.html ) , i have deploy it on heroku
that is the code in my app.js file that create the server
const express = require('express');
const app = express();
const path = require('path');
// create a server for socket io
const http = require('http');
const socketio = require('socket.io');
const server = http.createServer(app);
module.exports = io = socketio(server);
// my middle ware
const morgan = require('morgan');
const bodyParser = require('body-parser');
// Init Middelware
app.use(express.json({ extended: false }));
// my router
const postRoute = require('./nodeapi/routers/post');
const authRouter = require('./nodeapi/routers/auth');
const usersRouter = require('./nodeapi/routers/users');
const friendRouter = require('./nodeapi/routers/friend');
const chatRouter = require('./nodeapi/routers/chats');
const mongoDB = require('./nodeapi/mongodb-database/db');
const port = process.env.PORT;
// Connect monogo database
mongoDB();
// Middel ware
app.use(morgan('dev'));
app.use(bodyParser.json());
// Get the routes
app.use('/', postRoute);
app.use('/', authRouter);
app.use('/', usersRouter);
app.use('/', friendRouter);
app.use('/', chatRouter);
app.use('/file/', express.static('./uploads/'));
// connect to socket io
io.on('connection', (socket) => {});
//Serve static assets in productio
if (process.env.NODE_ENV === 'production') {
// Set static folder
app.use(express.static('./client/build'));
app.get('*', (req, res) => {
res.send(path.resolve(__dirname, '..', 'client', 'build', 'index.html'));
});
}
// listen to the port
server.listen(port, () => {
console.log(`this is port ${port}`);
});
this is when i open it for the first time
this is when i refresh the page
You just need to send it as file not a text
app.use(express.static('./client/build'));
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, '..', 'client', 'build', 'index.html'));
});

Socket.io: io.on('connection) repeats three times

The following is an excerpt from some server side code located in the entry point of the application:
const app = express()
const chatServer = require('http').Server(app);
chatServer.listen(3000)
const io = require('socket.io')(chatServer);
io.on('connection', (socket) => {
console.log('ABC')
socket.on('send-chat-message', message => {
socket.broadcast.emit('chat-message', message)
})
});
Upon running my dev server I expected to see 'ABC' print once to the console. However, it is printing three times (ABC, ABC, ABC) instead. Why does this happen? The io variable is NOT used anywhere else in the application. I'm pretty sure it has nothing to do with client side logic (since no requests are made by the client at this point) And for complete reference, the entire app.js code is displayed below:
const express = require('express')
require('./db/mongoose')
const playerRouter = require('./routers/player')
const contractRouter = require('./routers/contract')
const bodyParser = require('body-parser');
const hbs = require('express-handlebars')
const path = require('path')
const passport = require('passport');
const flash = require('connect-flash');
const session = require('express-session');
// Define paths for Express config
const viewsPath = path.join(__dirname, '../templates/views')
const partialsPath = path.join(__dirname, '../templates/partials')
const layoutPath = path.join(__dirname, '../templates/layouts')
const app = express()
const chatServer = require('http').Server(app);
chatServer.listen(3000)
const io = require('socket.io')(chatServer);
// Passport Config
require('./middleware/passport')(passport);
//Setup handlebars engine and views location
app.engine('hbs', hbs({
extname: 'hbs',
defaultLayout: 'main',
layoutsDir: layoutPath,
partialsDir: partialsPath,
}));
app.set('view engine', 'hbs')
app.use(express.static('public'))
app.set('views', viewsPath)
io.on('connection', (socket) => {
console.log('ABC')
socket.on('send-chat-message', message => {
socket.broadcast.emit('chat-message', message)
})
});
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.json())
// Express session
app.use(
session({
secret: 'secret',
resave: true,
saveUninitialized: true
})
);
// Passport middleware
app.use(passport.initialize());
app.use(passport.session());
// Connect flash
app.use(flash());
// Global variables
app.use(function (req, res, next) {
res.locals.success_msg = req.flash('success_msg');
res.locals.error_msg = req.flash('error_msg');
res.locals.error = req.flash('error');
res.locals.currentUser = req.user
next();
});
app.use(playerRouter)
app.use(contractRouter)
module.exports = app
Here is the client side code (for brevity I did not include the entire HTML file):
const socket = io('http://localhost:3000')
const messageContainer = document.getElementById('message-container')
const messageForm = document.getElementById('send-container')
const messageInput = document.getElementById('message-input')
socket.on('chat-message', message => {
appendMessage(`Opponent: ${message}`)
})
messageForm.addEventListener('submit', e => {
e.preventDefault()
const message = messageInput.value
appendMessage(`You: ${message}`)
socket.emit('send-chat-message', message)
messageInput.value = ''
})
const appendMessage = (message) => {
const messageElement = document.createElement('div')
messageElement.innerText = message
messageContainer.append(messageElement)
}
Sure, the message 'ABC' is rendered every time a connection to the client is established.
const express = require("express");
const path = require("path");
const app = express();
const http = require("http").Server(app);
const io = require("socket.io")(http);
// Here declare fiel static, as index.html, css, javascript.
app.use(express.static(path.resolve(__dirname, "../public")));
io.on("connection", socket => {
console.log("ABC");
socket.on("send-chat-message", message => {
socket.broadcast.emit("chat-message", message);
});
});
http.listen(8080, () => {
console.log("Starting...");
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<div id="message-container"></div>
<form id="send-container">
<input id="message-input" type="text" />
<button type="submit">submit</button>
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js"></script>
<script>
const socket = io();
const messageContainer = document.getElementById("message-container");
const messageForm = document.getElementById("send-container");
const messageInput = document.getElementById("message-input");
socket.on("chat-message", message => {
appendMessage(`Opponent: ${message}`);
});
messageForm.addEventListener("submit", e => {
e.preventDefault();
const message = messageInput.value;
console.log(message);
appendMessage(`You: ${message}`);
socket.emit("send-chat-message", message);
messageInput.value = "";
});
const appendMessage = message => {
const messageElement = document.createElement("div");
messageElement.innerText = message;
messageContainer.append(messageElement);
};
</script>
</body>
</html>
Here you can see the code working live.
I hope it helps. Any questions comment.
https://codesandbox.io/s/expressjs-chat-9v8lo

Resources