Can't connect to aedes MQTT broker - node.js

I've got an aedes MQTT broker and my MQTT client, but I can't seem to connect them.
In my app.js I do the following:
(async function () {
try {
await startBroker();
await mqttClient();
} catch (e) {
console.error("ERROR: ", e);
process.exit();
}
})();
My startBroker function start aedes and streams it like so:
const aedes = require('aedes')();
const server = require('net').createServer(aedes.handle);
const port = 1883;
exports.startBroker = function() {
return new Promise((res, rej) => {
server.listen(port, function () {
console.log(`MQTT Broker started on port ${port}`);
return res()
});
})
};
and then my mqttClient tries to connect, however I can never get to actually connect. I've tested it against the test mosquitto server which works fine
const mqtt = require('mqtt');
const client = mqtt.connect("mqtt://localhost:1883");
exports.mqttClient = function() {
console.log("Connecting to MQTT Client");
client.on("connect", ack => {
console.log("MQTT Client Connected!");
client.on("message", (topic, message) => {
console.log(`MQTT Client Message. Topic: ${topic}. Message: ${message.toString()}`);
});
});
client.on("error", err => {
console.log(err);
});
}
Does anyone know why my broker doesn't seem to be working?

Could you clarify, how the broker is not working and what actually works? Where and how do you run the code?
When I put the code into a single file (changing exports. into const), it does work. I had to add a semicolon after the function declaration of mqttClient, but after that, I get the following console output:
MQTT Broker started on port 1883
Connecting to MQTT Client
MQTT Client Connected!
This is the full code that can be copied right away. It runs in Node.js v12.15.0 on my macOS 10.15 Catalina.
const aedes = require('aedes')();
const server = require('net').createServer(aedes.handle);
const port = 1883;
// exports.startBroker = function() {
const startBroker = function() {
return new Promise((res, rej) => {
server.listen(port, function () {
console.log(`MQTT Broker started on port ${port}`);
return res()
});
})
};
const mqtt = require('mqtt');
const client = mqtt.connect("mqtt://localhost:1883");
//exports.mqttClient = function() {
const mqttClient = function() {
console.log("Connecting to MQTT Client");
client.on("connect", ack => {
console.log("MQTT Client Connected!");
client.on("message", (topic, message) => {
console.log(`MQTT Client Message. Topic: ${topic}. Message: ${message.toString()}`);
});
});
client.on("error", err => {
console.log(err);
});
}; // <-- semicolon added here
(async function () {
try {
await startBroker();
await mqttClient();
} catch (e) {
console.error("ERROR: ", e);
process.exit();
}
})();

this is my code for setting up mqtt broker with aedes. For settings up wss (connection with SSL) you will have to added one more configuration just like the ws part. Let me know if you need code for SSL also.
const express = require('express');
const aedes = require('aedes')();
const ws = require('websocket-stream');
const fs = require("fs");
const server = require('net').createServer(aedes.handle);
const app = express();
const ports = {
mqtt : 1883,
ws : 8080,
wss : 8081,
}
const host = '0.0.0.0' // localhost
server.listen(ports.mqtt, function () {
console.log(`MQTT Broker running on port: ${ports.mqtt}`);
});
// -------- non-SSL websocket port -------------
var wsServer = require('http').createServer(app)
ws.createServer({ server: wsServer}, aedes.handle)
wsServer.listen(ports.ws, host, function () {
console.log('WS server listening on port', ports.ws)
})

Related

Express and Websocket to run on the same port on the same file

I'm running two apps that sends real-time messages to each other using websocket and also generate a random link using express.js, now i hosted the server with both react apps to my vps host and want to make the websocket connection secure (wss://) but i realize i'll have to get the express server on the same port too, so the ssl/tsl works for both - so how do i do that?
Here is my full code, all on the same file:
const webSocketServerPort = 8000;
const webSocketServer = require('websocket').server;
const http = require('http');
const server = http.createServer(); server.listen(webSocketServerPort); console.log('Listening on port 8000');
const wsServer = new webSocketServer({ httpServer: server })
//GEERTOOOO
const express = require('express'); const cors = require('cors'); const fs = require('fs'); const app = express();
app.use(cors({ origin: '*' }));
app.get('/', (req, res) => { // Generate a random 6-character string const linkId = Math.random().toString(36).substr(2, 6);
// Save the link in the lex.json file fs.readFile('lex.json', (err, data) => { if (err) { console.error(err); res.status(500).send('Error generating link'); return; }
const links = JSON.parse(data);
links[linkId] = {
destination: 'http://localhost:4000/',
expires: Date.now() + 1000 * 60 * 5 // expires in 5 minutes
};
fs.writeFile('lex.json', JSON.stringify(links), (err) => {
if (err) {
console.error(err);
res.status(500).send('Error generating link');
return;
}
// Send the link back to the client
res.send(`http://localhost:3000/${linkId}`);
});
}); });
app.get('/:linkId', (req, res) => {
fs.readFile('lex.json', (err, data) => {
if (err) { console.error(err); res.status(500).send('Error retrieving link');
return;
}
const links = JSON.parse(data);
const link = links[req.params.linkId];
if (!link) {
res.status(404).send('Link not found');
return;
}
// Check if the link has expired
if (link.expires < Date.now()) {
res.status(410).send('Link has expired');
return;
}
// Redirect to the destination
res.redirect(link.destination);
}); });
app.listen(3000, () => { console.log('Server listening on port 3000'); });
//GEERTOOOO
const clients = {};
const getUniqueID = () => { const s4 = () => Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
return s4() + s4() + '-' + s4(); }
wsServer.on('request', (request) => { var userID = getUniqueID();
const connection = request.accept(null, request.origin); clients[userID] = connection;
connection.on('message', (message) => {
if (message.type === 'utf8') {
for(var key in clients) {
if (clients[key] !== clients[userID]) {
clients[key].sendUTF(message.utf8Data);
console.log(`Sent Message to: ${clients[key]}`);
}
}
}
}) })
Note: the express server is on port 3000 and the websocket server runs on port 8000.
I,ve tried just changing the port to same thing but i get an error when trying to use the websocket server for messages.
THE PURPOSE OF ALL THIS IS JUST TO MAKE THE WEBSOCKET CONNECTION AND EXPRESS CONNECCTION SECURE SO MY APPS (with letsencrypt ssl) can connect to the servers
It is not possible to create two separate server instances, both listening on the same port. But, specifically for a webSocket, you can share one server instance between Express and the webSocket server code. This is possible because a webSocket connection always starts with an http request (thus it can be listened for using your Express http server. And, because these http requests that initiate a webSocket all contain identifying headers they can be separated out from the regular http requests for Express by looking at the headers. The webSocket server code already knows how to do that for you.
To do that, first capture the Express server instance:
const server = app.listen(3000, () => { console.log('Server listening on port 3000'); });
Then, use that server instance when you create your webSocket server.
const wsServer = new webSocketServer({ httpServer: server });
Then, remove this code because you don't want to create yet another http server instance for the webSocket server:
const server = http.createServer();
server.listen(webSocketServerPort);
console.log('Listening on port 8000');

Why i have no response from my websocket?

I need your help because i have a node js server with websocket like this :
const app = require("../app"); // Basic app file
const server = require("http").createServer(app);
const WebSocket = require("ws");
const wss = new WebSocket.Server({ server });
wss.on("connection", (ws) => {
ws.send('message')
ws.on("close", () => {
console.log('connection closed'));
});
ws.on("message", (data) => {
console.log(data.toString());
});
});
server.listen();
And client side :
var ws = new WebSocket('wss://topicsall.fr',)
ws.onopen = function () {
console.log('open');
};
ws.onmessage = function () {
console.log('message');
};
I have no error message but the connection remains on hold and is interrupted after the elapsed time.
In dev mode I have no problem, it's only in production.
I've been stuck for 4 days, I really need your help! Thanks

Flutter Socket io disconnects after some seconds

Am using a local socket server using express which is expose to the internet using ngrok. This is the server code:
const app = require('express')();
const http = require('http').createServer(app);
app.get('/', (req, res) => {
res.send("Node Server is running. Yay!!");
});
//Socket Logic
const socketio = require('socket.io')(http)
socketio.on("connection", (userSocket) => {
console.log('Connected to socket');
});
http.listen(3000, () => {
console.log('listening on port 3000');
});
and my connection logic is:
void connectToServer() {
try {
socket = io('https://fa6387728fcd.ngrok.io', <String, dynamic>{
'transports': ['websocket'],
'autoConnect': false,
});
// Connect to websocket
socket.connect();
// Handle socket events
socket.on('connect', (data) => print('Connected to socket server'));
socket.on('disconnect', (reason) => print('disconnected $reason'));
socket.on('error', (err) => print('Error: $err'));
} catch (e) {
print(e.toString());
}
}
But i keep getting disconnected ping timeout or sometimes i get disconnected transport close
I had the same problem.
The problem wasn't caused by the socket_io_client package.
When i update socket.io on my server side, the problem is solved.
Just run npm install socket.io#latest command on your node.js server.
According to the socket_io_client official doc, use this workaround if you are using https server:
class MyHttpOverrides extends HttpOverrides {
#override
HttpClient createHttpClient(SecurityContext context) {
return super.createHttpClient(context)
..badCertificateCallback =
(X509Certificate cert, String host, int port) => true;
}
}
void main() {
HttpOverrides.global = new MyHttpOverrides();
runApp(MaterialApp(
...
));
}

Using Socker.io, emitting does nothing just after connecting

I just started using socket.io for my Node.js server. My problem is that I cannot emit anything immediately after connecting.
Nothing happens. No errors. But no emitting !
This is server:
const app = express();
const server = app.listen(3000);
const io = socket(server);
io.on("connect", (socket: Socket) => {
console.log("Client connected...");
// This does nothing
socket.emit("Sending immediately", 'sent!');
setTimeout(() => {
socket.emit("Sending with delay", 'delayed');
}, 1000);
}
And the client code is this:
(I'm checking the received messages in Firefox Network tab)
export class Server {
private io: SocketIOClient.Socket;
constructor() {
this.io = io('127.0.0.1:3000');
}
...
}

Node.js, how to keep server alive after a client exits?

I have a simple p2p app, but when I connect and exit as another peer or client the server stops completely. I've looked into connection.setKeepAlive, but it doesn't work they way I thought it would. I simply want the connection to any other peers to persist if another one exits.
const net = require('net')
const port = 3000
const host = 'localhost'
const server = net.createServer((connection) => {
console.log('peer connected')
})
server.listen(port, () => {
console.log('listening for peers')
})
const client = net.createConnection(port, host, () => {
console.log('connected to peer')
})
In your script the port on which the server listen is the same that you use for the client connection, so the application is calling itself.
Here is a script that connect to its peer and disconnect every 2 seconds:
const net = require('net')
const myPort = 3001
const peerPort = 3002
const host = 'localhost'
const server = net.createServer((connection) => {
console.log('peer connected')
})
server.listen(myPort, () => {
console.log('listening for peers')
})
let connectionTest = function() {
const client = net.createConnection(peerPort, host, () => {
console.log('connected to peer')
});
client.on('close', (err) => {
console.log("connection closed");
});
client.on('error', (err) => {
console.log("error");
});
//TODO do stuff
client.end();
setTimeout(connectionTest, 2000);
}
setTimeout(connectionTest, 3000);
For every instance you should change the ports (myPort & peerPort)

Resources