How to send end-of-stream character with node ipc? - node.js

I'm trying to end a IPC stream from my node app. I can't seem to figure out which character represents end-of-stream though and my stream never finishes.
const net = require("net");
const server = net.createServer((stream) => {
console.log("Server: on connection");
stream.on("data", (buffer) => {
console.log("Got data:", buffer.toString());
stream.write("This message ends here ->.");
});
stream.on("end", () => {
console.log("Stream ended");
server.close();
});
});
server.listen("\\\\.\\pipe\\myPipe", () => {
console.log("Listening...");
});
I have tried to add a null character (\u0000) to the end of my message and check for that on the receiving end, but that feels a bit hacky. Is there a way to send something like a end-of-stream character(s)?
Thanks!

Related

Stream video didn't have a duration exif

I do a website to record webcam in real-time on my server.
To do this, I use Web Socket to send data of my webcam to my Node.js Server.
The record is working, but my video didn't have a duration. In other words, I can't navigate in the video. I can just read the file second by second and can't skip segment or going back in the timer. (see the GIF below)
my server code to save video :
server.on("connection", (socket) => {
console.log("Client connected");
let writeStream = null;
let id = Date.now();
let filename = `${folderStream}/video-${id}.${extensionFile}`; // example : ./video/video-1620000000000.mp4
socket.on("message", (message) => {
if (!writeStream) {
console.log("Stream started");
writeStream = fs.createWriteStream(filename);
}
writeStream.write(message);
});
socket.on("close", () => {
console.log("Stream closed");
writeStream.end();
});
});
I try to use ffmpeg, but my video is already in one file and not segmented. (maybe bad usage by me)
For the future users who want to do the same thing, do this :
Create a temporary file who takes all raw data :
server.on("connection", (socket) => {
console.log("Client connected");
let tempFile = null;
let id = Date.now();
let filename = `video-${id}`; // exemple : video-1620000000000
socket.on("message", (message) => {
if (!tempFile) {
console.log("Stream started");
tempFile = fs.createWriteStream(`${folderStream}/${filename}.tmp`);
}
tempFile.write(message);
});
And with the library "fluent-ffmpeg";
npm i fluent-ffmpeg
const ffmpeg = require("fluent-ffmpeg");
Don't forget to install ffmpeg in your computer.
You can create a file transcoded after the ending stream.
socket.on("close", () => {
console.log("Fin d'un stream");
tempFile.end();
ffmpeg()
.input(`${folderStream}/${filename}.tmp`)
.format(extensionFile) // const extensionFile = "mp4"
.output(`${folderTranscode}/${filename}.${extensionFile}`)
.on("end", () => {
console.log("Conversion complete");
})
.run();
});
});

How to set transmission mode to message for pipes in Node.js?

This is my client code, I'm trying to send this message using pipes to a dotnet application (which uses "Message" as a tranmission medium, using bytes is not an option for me). The dotnet application is able to receive a message but the message seems to be malformed like below:
{⹹琠楨⁳獩愠猠牴湩Ⅷ}
`var net = require('net');
var PIPE_NAME = "TestServicePipeSender";
var PIPE_PATH = "\\\\.\\pipe\\" + PIPE_NAME;
var client = net.connect(PIPE_PATH, function () {
const str = "Hey. this is a string!";
client.write(str, "utf-8", () => {
console.log("Message Sent!")
})
})
client.on('data', function (data) {
console.log('Client: on data:', data.toString());
client.end('Thanks!');
});
client.on('end', function () {
console.log('Client: on end');
})`

How to end a request.js ServerResponse stream that never ends

I have this code to grab a video feed on command, but once started it never stops
async function getBandonBeachesOne(req, res, next) {
let timer = 0;
let videoURL =
"http://dizzyisadog.viewnetcam.com:50000/nphMotionJpeg?Resolution=640x480&Quality=Clarity";
let videoStream = request
.get(videoURL)
.on("data", function (data) {
timer++;
if (timer > 30) {
timer = 0;
console.log("received " + data.length + " bytes of compressed data");
}
})
.on("end", () => {
console.log("end");
})
.pipe(res);
req.on("close", () => {
console.log("Client left");
videoStream.end("end");
videoStream.destroy();//data keeps comming from the request.get(videoURL)
});
}
This is a request handler, it gets the video feed and pipes it to the client. Once the client leaves, I get the "Client left" message, but no maktter what I try, I can't stop the on('data') event form firing forever
Thanks to this answer here
I found the solution to be
videoStream.abort()

Node net socket.end event fires twice?

This event is firing twice. I'm trying to figure out why.
On one client, I have:
import Net from 'net';
import Chalk from 'chalk';
const fallback = [2,5,10,25,50,100,250,500,1000,2000];
class LocalNetworkInterface {
constructor({path}) {
this._sock = new Net.Socket();
this._pending = {};
this._count = 0;
this._retry = 0;
const connect = () => {
this._sock.connect({path});
};
this._sock.on('connect',() => {
this._retry = 0;
console.log(`Connected to ${Chalk.underline(path)}`);
});
this._sock.on('data',buffer => {
let data = JSON.parse(buffer);
this._pending[data.queryId].resolve(data);
delete this._pending[data.queryId];
});
this._sock.on('end', () => {
console.log(`Lost connection to ${Chalk.underline(path)}. Attempting to reconnect...`);
connect();
});
this._sock.on('error', err => {
if(err.code === 'ENOENT') {
let ms = fallback[this._retry];
if(this._retry < fallback.length - 1) ++this._retry;
console.log(`Socket server unavailable. Trying again in ${ms}ms`);
setTimeout(connect, ms);
}
});
connect();
}
// ...
}
And the server:
const sockServer = Net.createServer(c => {
c.on('data', buffer => {
let data = JSON.parse(buffer);
// log('Received',data);
let ql = queryLogger();
runQuery(Object.assign({}, data, {schema})).then(result => {
ql(`${Chalk.magenta('socket')} ${print(data.query).trim()}`);
let response = Object.assign({}, result, {queryId: data.queryId});
c.write(JSON.stringify(response));
});
})
});
sockServer.on('error', serverError => {
if(serverError.code === 'EADDRINUSE') {
let clientSocket = new Net.Socket();
clientSocket.on('error', clientError => {
if(clientError.code === 'ECONNREFUSED') {
FileSystem.unlink(SOCK_FILE, unlinkErr => {
if(unlinkErr) throw unlinkErr;
sockServer.listen(SOCK_FILE, () => {
log(`Sock server improperly shut down. Listening on '${sockServer.address()}'`)
});
});
}
});
clientSocket.connect({path: SOCK_FILE}, () => {
throw new Error(`Server already running`);
});
}
});
['SIGTERM','SIGINT'].forEach(signal => process.on(signal, () => {
console.log(`\rReceived ${Chalk.yellow(signal)}, shutting down ${Chalk.red('❤')}`);
sockServer.close();
process.exit();
}));
sockServer.listen(SOCK_FILE, () => {
log(`Listening on ${Chalk.underline(sockServer.address())}`)
});
When I restart the server, I see "Lost connection" twice on the client. Why?
The documentation says:
Emitted when the other end of the socket sends a FIN packet.
The server isn't sending two "FIN" packets is it? Any way I can verify?
Seeing this in docs in regard to connect...
"...This function is asynchronous. When the 'connect' event is emitted the socket is established. If there is a problem connecting, the 'connect' event will not be emitted, the 'error' event will be emitted with the exception."
The fact that the connect event might simply not be firing simply making it look to you like the end event fired twice? Like #robertklep said, maybe expand that error check for more than specific code.
I think it's because on end, I immediately try to reconnect and then the same event is being caught again. Seems kind of strange that it would do that, but delaying it to the next tick works:
this._sock.on('end', () => {
console.log(`${Chalk.yellow('Lost connection')} to ${Chalk.underline(path)}. Attempting to reconnect...`);
process.nextTick(connect);
});

Nodejs: How to send a readable stream to the browser

If I query the box REST API and get back a readable stream, what is the best way to handle it? How do you send it to the browser?? (DISCLAIMER: I'm new to streams and buffers, so some of this code is pretty theoretical)
Can you pass the readStream in the response and let the browser handle it? Or do you have to stream the chunks into a buffer and then send the buffer??
export function getFileStream(req, res) {
const fileId = req.params.fileId;
console.log('fileId', fileId);
req.sdk.files.getReadStream(fileId, null, (err, stream) => {
if (err) {
console.log('error', err);
return res.status(500).send(err);
}
res.type('application/octet-stream');
console.log('stream', stream);
return res.status(200).send(stream);
});
}
Will ^^ work, or do you need to do something like:
export function downloadFile(req, res) {
const fileId = req.params.fileId;
console.log('fileId', fileId);
req.sdk.files.getReadStream(fileId, null, (err, stream) => {
if (err) {
console.log('error', err);
return res.status(500).send(err);
}
const buffers = [];
const document = new Buffer();
console.log('stream', stream);
stream.on('data', (chunk) => {
buffers.push(buffer);
})
.on('end', function(){
const finalBuffer = Buffer.concat(buffers);
return res.status(200).send(finalBuffer);
});
});
}
The first example would work if you changed you theoretical line to:
- return res.status(200).send(stream);
+ res.writeHead(200, {header: here})
+ stream.pipe(res);
That's the nicest thing about node stream. The other case would (in essence) work too, but it would accumulate lots of unnecessary memory.
If you'd like to check a working example, here's one I wrote based on scramjet, express and browserify:
https://github.com/MichalCz/scramjet/blob/master/samples/browser/browser.js
Where your streams go from the server to the browser. With minor mods it'll fit your problem.

Resources