Cannot access Mosca mqtt broker deployed on Heroku - node.js

const express = require('express');
const helmet = require('helmet');
const bodyParser = require('body-parser');
const morgan = require('morgan');
const path = require('path');
const server = require('./modules/server');
const dashboard = require('./modules/dashboard');
const config = require('./config');
const routes = require('./routes');
const app = express();
app.use(helmet()); // secure http communication middleware
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(morgan('tiny')); // http request logger
app.use('/', routes);
app.use('/public', express.static(path.join(__dirname, '/public')));
// Serve the Parse API on the /parse URL prefix
const mountPath = process.env.PARSE_MOUNT || '/parse';
app.use(mountPath, server);
app.use('/dashboard', dashboard);
/**
* Mosca Server Settings below
*/
var mosca = require('mosca');
var http = require('http');
var httpServer = http.createServer(app);
var moscaSettingss = {
type: 'mongo',
url: 'mongodb://***:31157/mqtt',
pubsubCollection: 'pub_sub',
mongo: {}
};
httpServer= new mosca.Server({
backend: moscaSettingss,
persistence: {
factory: mosca.persistence.Mongo,
url: 'mongodb://***:31157/mqtt'
}
}, function() {
httpServer.attachHttpServer(app);
});
httpServer.on('ready', function() {
console.log('Mosca is running');
});
httpServer.on('clientConnected', function(client) {
console.log('client connected', client.id);
});
httpServer.on('published', function(packet, client) {
console.log('Published : ', packet.payload);
});
httpServer.on('subscribed', function(topic, client) {
console.log('subscribed : ', topic);
});
httpServer.on('unsubscribed', function(topic, client) {
console.log('unsubscribed : ', topic);
});
httpServer.on('clientDisconnecting', function(client) {
console.log('clientDisconnecting : ', client.id);
});
httpServer.on('clientDisconnected', function(client) {
console.log('clientDisconnected : ', client.id);
});
/**
* End of Mosca Server Settings
*/
app.listen(config.server.port, () => {
console.log(`Magic happens on port ${config.server.port}`);
});
module.exports = app;
I have made an express app, which contains mosca mqtt broker. Some how I cannot connect to that mqtt. Tried all possible urls.
In the express app, I made a mqtt client, which sucessfully connects with the broker. But out side Heroku, my devices are unable to connect.
Awaiting response.

Heroku will not open the port necessary for MQTT. This is why express can access it locally but none of your devices can.

I also try ws://mevris-cloud.herokuapp.com:80. It works!

Related

Express server and socket.io not working in same port

Not working can't find any issue in code##
If I put any port number instead of server it's working but why didn't it's working with socket server anyone explain
I tried some solution but none of them work I want to run socket.io and express on same port number
const express = require('express');
const cors = require("cors");
const socketIO = require('socket.io');
const http = require('http');
const app = express();
const server = http.createServer(app);
const passport = require("passport");
const authRoute = require('./routes/auth');
const userRoute = require('./routes/user');
const PORT = process.env.PORT || 9000;
const db = require('./config/mongoose');
app.use(express.json());
app.use(cors());
app.use(passport.initialize());
require("./config/passport")(passport);
app.use(express.json());
app.use("/api/auth", authRoute);
app.use("/api/user", passport.authenticate('jwt', { session: false }),userRoute);
if(process.env.NODE_ENV === 'production')
{
app.use(express.static('client/build'))
}
Here is the issue if I switch server to any port number it's fine
const io = socketIO(server, {
cors: {
origin: '*',
}
});
let state = {};
io.on("connection", (socket) => {
const { id } = socket.client;
socket.on('disconnect', function () {
console.log('socket disconnected!');
});
socket.on('join_room', function (data) {
console.log('joining request rec.', data);
socket.join(data.room);
io.in(data.room).emit('user_joined', data);
});
socket.on('send_code', function (data) {
io.in(data.room).emit('receive_code', data);
});
});
app.listen(PORT, function (err) {
if(err){
console.log(err);
return;
}
console.log(`Server is up and running on port: ${PORT}`);
});
http.createServer(app) and app.listen() are not compatible as they both try to do the same thing. If you look at the source code for app.listen(), you will see this:
app.listen = function listen() {
var server = http.createServer(this);
return server.listen.apply(server, arguments);
};
So, it's creating a DIFFERENT server object. You end up with two and the first one never gets started so when you give it to socket.io, it never works.
Instead, remove this:
const server = http.createServer(app);
And, use this instead:
const server = app.listen(PORT, function (err) { ...});
This way, your server variable will contain the one and only server object that is actually running.
Alternatively, you could remove the app.listen() and then just add this in it's place:
server.listen(PORT, ...);
The general idea is that you want this pair:
const server = http.createServer(app);
server.listen(PORT, ...);
Or, just this:
const server = app.listen(PORT, ...);
You cannot use both. Either way, that server object will represent the server that is actually running and will work with socket.io.

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.

404 error with express and express-ws

I'm having trouble trying to figure out why I'm getting this 404 error. I've gone through all the other questions on this site that cover 'express-ws' and i've modeled my code exactly how the solutions prescribed yet the websocket won't make a connection. I'm trying to create a websocket connection between my express server and react app. Below are previews of my code:
Express using express-ws (server.js):
var express = require('express');
var expressWs = require('express-ws');
var bodyParser = require('body-parser');
var cors = require('cors');
var nodemailer = require('nodemailer');
var email = require('./credentials');
var port = process.env.PORT || 3001;
var path = require('path');
// const WebSocket = require('ws');
// const http = require('http');
expressWs = expressWs(express());
let app = expressWs.app;
var server = require('http').createServer(app);
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
if (process.env.NODE_ENV === 'production') {
app.use(express.static('app/build'));
}
app.get('/', function(req, res){
console.log('server running!');
res.end();
});
app.ws('/ws', function(ws, req) {
console.log( 'socket running!' );
});
server.listen(port);
console.log('server started on port ' + port);
The GET route works fine but the ws route doesn't.
Call to express from React app:
componentDidMount() {
let ws = new WebSocket('ws://localhost:3001/ws');
ws.on( 'open', function open() {
console.log('app connected to websocket!');
} );
ws.on( 'message', function ( message ) {
console.log( message );
})
}
I've looked at all the following questions and don't understand why their solutions don't work for me:
Socket.IO 404 Error
express-ws connection problem
Node not working with express-ws
If anyone can let me know what's going on that would be great.
It seems your code does not follow express-ws's document. To use express-ws and make WebSocket endpoint, the code would be as:
var express = require('express');
var app = express();
var expressWs = require('express-ws')(app);
...
app.ws('/', function(ws, req) {
ws.on('message', function(msg) {
console.log(msg);
});
console.log('socket running');
});
app.listen(3000);
In the client side, ws object does not have field on. To listen WebSocket connection and message, you can use onopen and onmessage:
ws.onopen = function() {
console.log('app connected to websocket!');
};
ws.onmessage = function(message) {
console.log( message );
};
I had this exact problem and for me the solution was to change:
server.listen(port);
to:
app.listen(port);
I suspect what is going on is that express-ws is using the app listen function as its cue to start upgrading connections to ws and this won't happen if the server listen port occurs instead.

req.body undefined on server side

I am working on app which uses node, express, mysql on server side. i have written serveral APIs on server.js file and when i am trying to access those using Postman then req.body is always undefined.
this is my server.js configuration.
var express = require('express');
var mysql = require('mysql');
var cors = require('cors');
var bodyParser = require('body-parser');
var wrench = require("wrench");
var fs = require('fs');
var path = require("path");
var mkdirp = require('mkdirp');
var walk = require('walk');
var fse = require('fs-extra');
var multipart = require('connect-multiparty');
var multipartMiddleware = multipart();
var crypto = require('crypto');
app.use(cors());
app.use(bodyParser.urlencoded({limit: '50mb',extended: false}));
app.use(bodyParser.json({limit: '50mb'}));
var connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'pass',
database: 'dbname'
});
connection.connect(function(err) {
if (!err) {
console.log("Database is connected ... \n\n");
} else {
console.log("Error connecting database ... \n\n");
}
});
app.post('/urlreq', function(req, res){
console.log(req.body);
}
app.listen(3000, function(){
console.log("Rest Demo Listening on port 3000");
});
When i am trying send something in body in Postman then req.body is coming empty on server side.
If you are sending multipart/form-data, it doesn't work because bodyparser doesn't handle this body type.
In this case adding the following line should fix it:
app.use(multipartMiddleware);
Form the docs:
multipart/form-data is the default encoding a web form uses to transfer data
Try add:
var express = require('express');
var app = express();
[...]
// Last stack
app.listen(3000, function(){
console.log("Rest Demo Listening on port 3000");
});
You can use as a middleware also. Also listen on a port. add following lines in your code -
var app = express();
app.use(function(req, res, next) {
console.log('Current User:', req.body);
next();
});
app.post('/url', function(req,res){
console.log(req.body)
});
app.listen(3000, function(){
console.log('Express server listening on port 3000');
});

Resources