Connect to MQTT Broker With Device and Browser - node.js

I can create an MQTT broker. I can create a web client also. but there is a problem with the device. I try to connect with the IP(ws://192.168.1.240:1883) of the device. The device could not connect to the broker. Web client could connect with WebSocket.
const aedes = require('aedes')()
const httpServer = require('http').createServer()
const ws = require('websocket-stream')
const port = 1883
ws.createServer({ server: httpServer }, aedes.handle)
httpServer.listen(port, function () {
console.log('websocket server listening on port ', port)
});
I try to use another way to create an MQTT broker and it runs. code is below. this time device connected to the broker. But the Web browser could not connect to the broker. The browser wants to connect ws://192.168.1.240:1883. So the browser wants WebSocket.
const aedes = require('aedes')()
var server = require('net').createServer(aedes.handle);
var cors = require('cors');
const ip = "192.168.1.240";
const port = 1883;
const httpServer = require('http').createServer();
const io = require('socket.io')(httpServer, {
cors: {
origin: "*",
credentials: true
}
});
httpServer.listen(8091, () => {
console.log("Http Server and Socket.io are Running !");
});
server.listen(port, ip, () => {
console.log("TCP Server is Running !")
});
How can I create connectable a broker or server for devices and browsers?
Thanks

If you want to use both MQTT over Websockets and native MQTT you will need to configure the broker to listen on 2 separate ports. You can't listen for both on the same port.
e.g. This will accept native MQTT connections on 1883 and Websocket connections on 8883
const aedes = require('aedes')()
const server = require('net').createServer(aedes.handle)
const httpServer = require('http').createServer()
const ws = require('websocket-stream')
const port = 1883
const wsPort = 8883
server.listen(port, function () {
console.log('server started and listening on port ', port)
})
ws.createServer({ server: httpServer }, aedes.handle)
httpServer.listen(wsPort, function () {
console.log('websocket server listening on port ', wsPort)
})

Related

Socketio not connecting on postman socket connection ui on localhost

Could not connect to localhost:3000
17:02:53
Error: Unexpected server response: 404
Handshake Details
Request URL: http://localhost:3000/socket.io/?EIO=3&transport=websocket
Request Method: GET
Status Code: 404 Not Found
My express server listen on 3000 port and socketio http on 443 port, i am able to connect socket by hosting this on ec2 instance and using ec2 ip with port number on postman socket connection ui, but on localhost connection always failed with above error on postman socket beta ui.
You need to call listen only once. If you pass your http/https server to express, app.listen() is enough. (except you want to listen on 2 different ports.. For testing, let's call it only once.)
For accessing it on localhost try setting it explicitly with the parameter hostname in app.listen().
Example:
async function startServer() {
const app = express();
const credentials = {key: key, cert: crt};
const httpsServer = createServer(credentials,app);
const io = socketIO(httpsServer);
await require('./loaders').default({ expressApp: app, socketIO: io });
// Let's only call listen once for testing purposes. If you call
// listen on the express app, your https server will automatically listen
// to the same configuration.
// httpsServer.listen(4000);
const port = 3000
const hostname = 'localhost'
// explicitly let the app listen on localhost. If hostname is not
// provided, it will take the first found ipv4 interface
app.listen(port, hostname, err => {
if (err) {
Logger.error(err);
process.exit(1);
return;
}
Logger.info(`
################################################
🛡️ Server listening on https://${hostname}:${port} 🛡️
################################################
`);
});
}
Now you should be able to connect your socket. If it still does not work try
to use http module instead of https for better isolating your problem.
Note that your server now only will be accessible using localhost and not over ip. Both may only be possible when running 2 server instances with different hostnames.
async function startServer() {
const app = express();
const credentials = {key: key, cert: crt};
const httpsServer = createServer(credentials,app);
const io = socketIO(httpsServer);
await require('./loaders').default({ expressApp: app, socketIO: io });
httpsServer.listen(443);
app.listen(config.port, err => {
if (err) {
Logger.error(err);
process.exit(1);
return;
}
Logger.info(`
################################################
🛡️ Server listening on port: ${config.port} 🛡️
################################################
`);
});
}
This is my app.ts file, I am using Ubuntu. so 443 port is not allowed, i changed this port to 4000, now the app listen on the 3000 and socket http server on 4000, but socketio not able to connect with socket url localhost:3000

NodeJS as Websocket client using ws

I need to send a message to a websocket server through request POST. The client is not a browser but a Node server.
I'm new to websocket.
When I run the code below.
var WebSocket = require("ws");
const express = require("express");
var app = express();
const client = new WebSocket(process.env.URL);
client.on("error", handleError);
client.onopen = () => {
client.send("Message From Client");
};
function handleError(error) {
console.log(error);
}
app.get("/echo", async function (req, res) {
client.once("connection", function connection(cli) {
cli.send(msg);
res.send("send");
});
});
app.listen(3333, function () {
console.log("Example app listening on port 3333!");
});
It shows the error
Error: write EPROTO 19524:error:1408F10B:SSL routines:ssl3_get_record:wrong version number:c:\ws\deps\openssl\openssl\ssl\record\ssl3_record.c:332:
at WriteWrap.onWriteComplete [as oncomplete] (internal/stream_base_commons.js:92:16) {
errno: 'EPROTO',
code: 'EPROTO',
syscall: 'write'
}
I'm not sure how to do it with express, but it should be similar to https. Here is how to do it with https.
Basically it has to be the https server that should listen on certain port and also have certs and keys as option passed to it. Then you would pass the https server to websocket server.
When client connects, it'll connect to https and then upgrade to WSS.
Which means your client application can connect to wss://test.mysite.com:1234.
const https = require('https')
const options = {
cert: fs.readFileSync('/etc/ssl/test.mysite.com/cert.pem'),
key: fs.readFileSync('/etc/ssl/test.mysite.com/privkey.pem'),
ca: fs.readFileSync('/etc/ssl/test.mysite.com/chain.pem')
};
const httpsServer = https.createServer(options);
httpsServer.listen(1234, () => console.log('Https Server running on port 1234'));
var ws = new WebSocket.Server({
server: httpsServer
});
ws.on('connection', socket => {
console.log('Conencted')
});

How to troubleshoot problem with setting WebRTC server on vps?

I wrote a simple node express server for webRTC using peerjs-server and simple client using peerjs. Everything works fine on localhost, but when I try it on vps, I get error:
Firefox can't connect with server ws://my.vps/peerjs/peerjs?key=peerjs&id=hj3hpekwaa38fr00&token=ymtfvhagiw
PeerJS: Socket closed.
PeerJS: ERROR Error: Lost connection to server.
Error: "Lost connection to server."
emitError https://cdnjs.cloudflare.com/ajax/libs/peerjs/0.3.16/peer.min.js:1:16426
_initializeServerConnection https://cdnjs.cloudflare.com/ajax/libs/peerjs/0.3.16/peer.min.js:1:12260
emit https://cdnjs.cloudflare.com/ajax/libs/peerjs/0.3.16/peer.min.js:1:25516
onclose https://cdnjs.cloudflare.com/ajax/libs/peerjs/0.3.16/peer.min.js:1:19350
Server:
const express = require('express');
enter code here`const app = express();
const ExpressPeerServer = require('peer').ExpressPeerServer;
app.use(express.static('./public'));
const server = app.listen(80, () => { // 3000 on localhost
console.log('Express server listen on port ' + 80);
});
const options = { debug: true };
const peerserver = ExpressPeerServer(server, options);
app.use('/peerjs', peerserver);
app.use('/*', express.static('./public/index.html'));
Client:
var peer = new Peer('', {
host: location.hostname,
port: location.port || (location.protocol === 'https:' ? 443 : 80),
path: '/peerjs',
debug: 3
});
peer.on('open', function (id) {
console.log(id);
});
Any help appreciate.
It looks like you are connecting with server ws://my.vps/, which is a web socket to a server at http://my.vps/ which doesn't seem to exist.
It should probably also be using https (or wss)

Cant connect to WebSocket Node.JS

i'm making a game that use WebSockets and this is the code that i use to start a WebSocket server:
const server = require("http").Server(app);
const port = 3005;
server.listen(port, () => {
console.log('Server started on port: ' + port);
});
var WebSocketServer = require('ws').Server;
var wss = new WebSocketServer({ server })
wss.on('connection', function connection(ws) {});
And this code i use for connecting a user to the WebSocket:
this.SERVER_URL ='ws://localhost/?fvukovic'; <-- fvukovic is the user
this.ws = new WebSocket(this.SERVER_URL, ["test"]);
this.ws.onopen = () => {
console.log('open');
};
This works perfectly, but when i push that on server and i change the ip address to 195.201.119.221 which is the ip of the server, port is still 3005, i cant connect to it anymore..
I get this error:
WebSocket connection to 'ws://195.201.119.221:3005/?fvukovic' failed: Error in connection establishment: net::ERR_CONNECTION_TIMED_OUT
Do i need something more when i put the the app on a real server?

Https server with socket and express

I'm using SSL to encrypt my backend but my current solution opens two ports, one for sockets and the other for express, any approach to start both on the same port like HTTP ?
const port=4000;
if(process.env.ENABLE_SSL=='true')
{
////two ports are open 8989,4000
server = https.createServer({
key: fs.readFileSync("sslLocation/ssl.key"),
cert: fs.readFileSync("sslLocation/ssl.cert")
},app).listen("8989", '0.0.0.0',function(){
console.log('Express server listening to port 8989');
});
global.io = require('socket.io').listen(server);
app.listen(port);
}
else
{
////one port only
// start the server
server = app.listen(port, function () {
console.log(`App is running at: localhost:${server.address().port}`);
});
global.io = require('socket.io').listen(server);
}
also running app.listen(server) in the ssl section, i can't access the apis

Resources