Updating serial port data on webpage with Node JS - node.js

I am reading data from the serial port using Node JS (which I am quite new to at the moment). Although I can see the data through an stdout stream via console.log and get a static value on the webpage I cannot get the value to update on a continuous basis. My current code looks like this:
var http = require('http');
const SerialPort = require('serialport');
const Readline = require('#serialport/parser-readline');
const port = new SerialPort('/dev/ttyACM0', { baudRate: 9600 });
const parser = port.pipe(new Readline({ delimiter: '\r\n' }));
http.createServer(function (request, response) {
parser.on('data', (data) => {
console.log(data);
response.writeHead(200, {"Content-Type":"text/html"});
response.write(data);
});
}).listen(8888);
Is there a way I can get the serial data to update in realtime on the webpage as opposed to having to refresh the page?
Node JS version: v12.18.2

Depending on how often you want the page to update on the webpage, you could serve the most recent reading via an express api, or using something like socket io. Using express is a simpler but less real time. Socket io will be able to update in real time. https://socket.io/

Related

Axios can GET but not POST to the same URL

I'm building a react app
In one component I'm writing this GET request which works:
In another component I'm writing this POST request:
Which then returns this 404 error:
And I have no idea how my GET works but my POST returns 404:not found when I'm requesting the same file both times?
UPDATE:
I'm running a node.js server now but it's a bit of a frankenstein's monster as this really isn't an area I have an understanding of. Does anyone know what I'm doing wrong?
// Server setup from node.js website
const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World\n');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
// Trying to listen for data from React app to feed into JSON (broken)
var express = require("express");
var myParser = require("body-parser");
var app = express();
app.use(myParser.urlencoded({extended : true}));
app.post("/scene-setup.json", function(request, response) {
console.log(request.body); //This prints the JSON document received (if it is a JSON document)
});
app.listen(3001);
// Updating JSON file with "obj" (working)
var jsonfile = require('jsonfile')
var file = './scene-setup.json'
var obj = {name: 'JP'}
jsonfile.writeFile(file, obj, function (err) {
console.error(err)
})
Axios is used for making HTTP requests. So, you should have a backend server running that can handle these requests. I am not sure what exactly is the data that you want to save. If you need access to that data, should be saving it on the backend.
If you want to save some data just on the client side, HTML5 filesystem API might be something you want to look at. It can manage some data in the limited sandboxed part of user's filesystem.

data exchange via localhost in node.js

in the following code, app1.js sends information on localhost port 3000
//app1.js
var http = require('http');
const valueToTransfert = 'test';
var server = http.createServer(function(req, res) {
res.end('valueToTransfert');
});
server.listen(3000);
I want to make a second program app2.js that will run simultaneously and read data sent by app1.js on localhost:3000.
How can I do that ?
Thank you for your help
This is a bit of a hack but it might work your your immediate purposes
require('child_process').exec('node app2.js test', function(err, stdout, stderr) {
// you get your results in stdout
// app2.js would have to output its result with console.log(...);
});
But if you need to send more data you will probably have to setup another server, or do something a bit more complex.

NodeJs Google Speech API Streaming

I've been trying to setup a node service for streaming live audio to the Google Speech API, but I've hit a problem that I think might be authentication related.
The service is written in node using Express and BinaryServer, I'm receiving data without any problems (and have been able to save it to the local disk, but that section of code isn't in the below example), but when I try to submit to the Google API I don't receive anything back (Although if I remove the keyFileName from the request then I get "Error: Could not load the default credentials" which is fair enough because I'm running outside the GCE)
var express = require("express");
var app = express();
var port = 54180;
var BinaryServer = require('binaryjs').BinaryServer;
var server = BinaryServer({
port: port
});
app.listen(port, function () {
console.log('server open on port ' + port);
});
binaryServer = BinaryServer({
port: 9001
});
binaryServer.on('connection', function (client) {
console.log('Binary Server connection started');
client.on('stream', function (stream, meta) {
console.log('>>>Incoming audio stream');
var speech = require('#google-cloud/speech')({
projectId: 'MYPROJECT-1234'
//keyFilename: '/config/KeyFile.json'
});
const request = {
config: {
encoding: 'LINEAR16',
sampleRate: 16000
},
singleUtterance: false,
interimResults: true
};
// Create a recognize stream
const recognizeStream = speech.createRecognizeStream(request)
.on('error', function (error) {
console.log('Error');
console.log(error)
})
.on('data', function (data) {
console.log('Data');
console.log(data);
});
// Send the microphone input to the Speech API
stream.pipe(recognizeStream);
stream.on('end', function () {
fileWriter.end();
recognizeStream.end();
console.log('||| Audio stream ended');
});
});
});
I'll also admit this is the first time I've tried to re-pipe to another API, so it could be that I've screwed that part up, but the default credentials message makes me think it's piping OK and it's just rejecting my request without returning a reason.
Can anyone spot what I'm getting wrong?
Cheers.
See Shiv's question for the answer to this problem
NodeJS Convert Int16Array binary Buffer to LINEAR16 encoded raw stream for Google Speech API
The code answer he gave was
We can write the buffer directly to recognizerStream which created from
GoogleSpeech as follows:
const recognizer = getGoogleSpeechStreamRecognizer();
recognizer.write(int16ArrayBuffer)

ConnectJS + RequireJS hanging after a few reloads

I got a fairly massive requirejs based app that runs unbundled locally. I have a few hundred js files that get loaded in async. This is pretty quick locally and generally not a big deal. After maybe 10->20 page refreshes connectjs starts hanging for some reason. I got a half decent message once when I opened a different page and chrome indicated "waiting for available socket."
I'm guessing that at some point something ends up hanging and the connection never ends. At some point enough of these connections results in Node + connect to not accept any more requests. Has anyone experienced this and what is the solution? Is there a way to time out or reject requests from the server side?
Here is my connectjs server script:
var connect = require('connect');
var http = require('http');
var app = connect()
.use(connect['static'](__dirname))
.use(function (req, res) {
'use strict';
res.setHeader('Access-Control-Allow-Origin', '*');
// used to stub out ajax requests
if (req.url.indexOf('ajax/') !== -1) {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({}));
}
});
var server = http.createServer(app);
server.listen(3000, function () {
'use strict';
console.log('server is listening on port 3000');
});

pass port number to page loaded in node.js/socket.io

Okay, I have a simple test server set up using socket.io in node.js. My goal is to run the same server on a few different ports to test some load balanced conditions and synchronization tests.
Here is what the server looks like:
var app = require('http').createServer(handler),
io = require('socket.io').listen(app),
fs = require('fs'),
port = process.argv[1]; // listen on port number passed via command line
app.listen(port);
function handler (req, res) {
console.log('request', {remotePort: req.connection.remotePort, remoteAddress: req.connection.remoteAddress, url: req.url});
// how do I pass the port number here?
fs.readFile(__dirname + '/chat.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading chat.html');
}
res.writeHead(200);
res.end(data);
});
}
io.sockets.on('connection', function (socket) {
// do chatty stuff
});
The question is: what is the easiest way to get the port number into chat.html (see comment in code above)? Is there a way to do this with node or fs? Do I need to Express set up with templates?
Wonder what node will let me do with the query string; could I just stick the port in there and pick it out with jQuery once the page loads?
Thanks, in advance!
html is for static contents. so you can not use for dynamic contents.
so easiest way is using templates like ejs, jade and jquery template.
but you don't want you can change contents from chat.html
function(err, data) {
data = data.replace() // like this
}
I'm not recommend this way.
This is an old question, but decided to answer it with a more suiting answer still.
Because you're listening on the same port on both the http and socket.io, you can just change the script on the client to connect to the same address as the webpage was loaded, like so:
var socket = io.connect(window.location.href);
If the server was just a normal websocket server, you could do instead this:
var socket = new WebSocket(window.location.href.replace('http', 'ws'));

Resources