using MQTT.js (node package) in electron to update dom - javascript

I am new to electron and node.js working on mqtt to update the DOM. I receive message on mqtt to my main.js onmessage function and my main.js is
const { app, BrowserWindow } = require('electron')
var mqtt = require('mqtt')
var client = mqtt.connect("mqtt://localhost")
client.on("connect", function(){
client.subscribe("testtopic")
})
client.on("message", function(topic, message, packet){
document.getElementById("someId").innerHTML = message
})
function createWindow () {
const win = new BrowserWindow({webPreferences:{nodeIntegration: true}})
win.loadFile('index.html')
win.maximize()
}
app.whenReady().then(() => {
createWindow()
})
And I would like to update the element which is available in index.html from my onmessage callback. I cannot access it shows error document is not defined.
How to achieve this or can I import mqtt directly in my index.html script ?
in that case why use node mqtt instead I can use paho mqtt.
Please advice on this.

That code is running in the "backend" not in the browser, so will have no access to the DOM.
If you want update the DOM in response to MQTT messages you have a couple of choices.
Implement a MQTT over WebSockets in the index.html file that will subscribe to the broker directly in the page and will have direct access to the DOM. You can use either the MQTT.js or the Paho client in the page, but you will need a broker that has specifically been configured to support MQTT over WebSockets.
Look at setting up some direct connection between the backend code and the loaded page, the following question might help with some pointers: How to access DOM elements in electron?

Related

Trigger a javascript function from nodejs backend

I'm building an interactive aplication for kids. I'm working with some sensors that sends UDP data and I need to do something with that on screen.
I want to work with node js in order to receive these udp commands (that's fine for me). The problem is that I can't find the way that node trigger some function to the frontend javascript vanilla. Is there a way to do that? I know I can comunicate java with node using post and emit, but for that, java must make the request first and wait for a concrete answer, in this case, frontend must be always waiting for node commands.
Thanks in advance!
It is possible to push from the server to the client if you first establish a connection using Websockets. The alternative approach is to frequently poll the server.
To use websockets, grab a library such as ws by using npm install ws and basically follow their docs. Example from their docs:
import { WebSocketServer } from 'ws';
const wss = new WebSocketServer({ port: 8080 });
wss.on('connection', function connection(ws) {
ws.on('message', function incoming(message) {
console.log('received: %s', message);
});
ws.send('something');
});

Can't connect to socket.io server from Node JS script

I've got a socket.io server running on Node JS listening for messages. I now need to start another Node JS script (my client) which will send messages to the server, that's at a specific URL and port.
I'm passing my URL into the connect function but am getting the error:
TypeError: io.connect is not a function
How can I pass my URL to connect to into this. My script is:
const io = require('socket.io');
const socket = io.connect('http://localhost:3000');
socket.on('connect', function () {
socket.send('hello') // send to server from running JS script
});
If you're attempting to initiate a socket.io connection from node.js, you need the client-side library which would be:
const io = require('socket.io-client')
And, of course, you have to install that library.

Execute NPM module through cordova

I created an app using cordova and everything is fine, expect I need to use a node module which doesn't have a client-side equivalent because I'm dealing with file write streams etc. I have found Cordova hooks to be my best shot so far, where I create an app_run hook to execute a node file that runs a socket server to listen for events from the client side.
I know, a very longwinded solution, but seems logically correct to me, the issue is that when I do create the server, building the app through Visual Studio 2017, the app launches on my android phone, but VS hangs on the "deploy" stage. I guess that it has to do with the event chain, so I created an asynchronous script like this:
(async function () {
const server = require('http').createServer()
const io = require('socket.io')(server)
io.on('connection', function (socket) {
console.log('heyo')
socket.emit('hello world', 'hi')
})
server.listen(3000, function (err) {
if (err) throw err
console.log('listening on port 3000')
})
})();
but this doesn't seem to work either, somehow VS hangs on "deploy". If anyone can possibly guide me in the right direction, that would be highly appreciated.
PS: I know the title is off, but every time I use StackOverflow to get help with a particular attempt, I'm told to do it another way, so I'll leave it open.
If the goal is to use socket.io in your cordova app, there IS a JS client for the web that you need to use and you don't need to use npm for that, just add a link to your client js file in your index file. (should be in a "client" folder when you init socket.io via npm).
<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io('http://localhost');
</script>
https://socket.io/docs/client-api/

Why socketIO call too much connections?

I created my Socket server with Express, SocketIO and Redis
server.js
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var redis = require('redis');
server.listen(8890, function (e) {
console.log(e);
});
io.on('connection', function (socket) {
console.log("new client connected");
var redisClient = redis.createClient();
redisClient.subscribe('message');
redisClient.on("message", function(channel, message) {
console.log("mew message in queue "+ message + "channel");
socket.emit(channel, message);
});
socket.on('disconnect', function() {
redisClient.quit();
});
socket.on('connect_error', function() {
redisClient.quit();
});
});
From command line, I run node server.js. Its worked.
I also created a html file to connect to that server.
From Browser Console, I run io.connect('http://localhost:8890'). I got as the result
As I see, too much connections (requests).
What happens? What wrong from my code?
You have mismatched client and server versions causing the initial connection to fail and the older client is dumb enough to just keep trying over and over again. If you are using 2.0.4 on the server, then you must use that version for the client too. If you serve the client version directly from your server with:
<script src="http://localhost:8890/socket.io/socket.io.js"></script>
Then, the socket.io server will automatically give you the right client version.
Or, you can manually link to the right version on your CDN such as https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.4/socket.io.js. But client and server versions MUST match.
The advantage of getting the client directly from your own server is that anytime you update your server version of socket.io, the client version will automatically be upgraded for you and kept in perfect sync since the matching client version is built into the server version.

Why do I get a Bad request when I run server.js and client.js and access localhost?

I am new to node.js
I am trying to use the pub/sub faye nodemodule to create a publish/subscribe web application.
I have the following files and folders: My dependencies in the node_modules folder, a sever.js file, and a client.js
My server.js contains the following code:
var http = require('http'),
faye = require('faye');
var server = http.createServer(),
bayeux = new faye.NodeAdapter({mount: '/'});
bayeux.attach(server);
server.listen(8000);
As for my client.js file, it contains the following code:
var faye = require('faye')
var client = new faye.Client('http://localhost:8000/');
client.subscribe('/messages', function(message) {
alert('Got a message: ' + message.text);
});
client.publish('/messages', {
text: 'HAI!'
})
I go to my terminal and run node server.js and node client.js
When I go to my browser and run localhost:8000, all I get is a Bad request.
Why am I getting this? I am suspecting I don't have any page to display something.
Could someone please point out to me what I am missing.
Thanks.
You're getting that error because you've mounted Faye at /. So if you try browsing to /, the server is expecting a Faye client, not a normal HTTP request.
There is a browser client example that shows how to connect with Faye mounted at /faye. You can also pass in a request handler into http.createServer() that allows you to handle the request before Faye does, in case you want to respond to the particular request.

Categories