Running external programs through nodejs and interacting with browser through socket.io - javascript

While trying to create a tool(with nodejs, socket.io) which runs an external program (e.g. a C program or a Python program), the program stops responding when it encounters the user input (it sends the line asking input to browser though).
On Server:
var chunk = '';
python.stdout.on('data', function(data){
python.stdout.pipe(python.stdin);
chunk += data;
console.log(chunk);
socket.emit('newdata', chunk);
} );
On Client:
socket.on('newdata', function(d){
var output = document.getElementById('output');
output.innerHTML = d;
})

Everything is working fine in fact, the only problem is that the program you launched requires a user input and your node.js code is not giving it.
Tbh I don't know if you can give an input when it asks for it... but can't you pass arguments at the start of the program to avoid this user input? It's how I solved it on the same system done with Java/J2EE

Related

Can this Python script be made in JavaScript?

I'm very new to computer programming, and me and some friends are making a small project that chooses a random line of text from a text file full of data. I have a Python script that chooses a random line of a text file and returns it.
import random
filePath = "../data/strats.txt"
count = len(open(filePath).readlines( ))
lineNum = randint(1, count)
lines = [0]
with open(filePath) as strats:
while strats.readline():
lines.append(strats.tell())
strats.seek(lines[lineNum])
line = strats.readline()
return line
This connects to some JavaScript code, but I'm having trouble using the python script without a web server. I would like to make the website all client side, and that means making this same program in JavaScript. If there is another way, please let me know. Otherwise: Can this Python script be translated into JavaScript?

Is there a JavaScript/jQuery File Create event?

For some reason I got stuck with some events on jQuery/JS
function update()
{
if(scrolling == true) {
return;
}
var count = 0;
jQuery.get('count.txt', function(data) {
count = data;
}).done(function() {
var countstr = '' + count;
myImage.src = "latest" + countstr + ".jpg#" + new Date().getTime();
setTimeout(update, 1000);
});
}
In my last question I asked about the jQuery "done function"
Currently I am working with a Timeout/timer to update the image every second
setTimeout(update, 1000);
It does work but I know that this can't be the smartest solution. In C# I'm able to use a FileWatcher to use an event to check if there is a new file in the folder
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = path;
watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
| NotifyFilters.FileName | NotifyFilters.DirectoryName;
watcher.Filter = "*.jpg";
watcher.Created += new FileSystemEventHandler(OnChanged);
watcher.EnableRaisingEvents = true;
Is there an API or an event for jQuery/JS to check that? I was also looking to work with AJAX but I got no experiences with AJAX.
//edit
I know that JS is not able to do that. But I was just wondering if there is another way to use this event (like AJAX or Node.js)
What Am I doing?
I made a software which will upload many images on my ftp server. images0, images1, images2 etc.
The event should check if there was another image uploaded and should show this instead of the old image
Florian, as it was already mentioned, you cannot do it with client JS code.
What would I use in this case (I assume it's the universal solution):
NodeJS has file watching API (https://nodejs.org/docs/latest/api/fs.html#fs_class_fs_fswatcher), thus, you can subscribe to FS events.
You should notify client about this changes. I would use soket.io ( https://socket.io/ , both client and server side).
Using the file watcher and websokets you can notify user about any FS changes. You can upload files using FTP, HTTP client or just create them locally.
Clientside/Frontend Languages won't able to create/edit/delete a File
It can only read a File
for writefile in node js ..its already in stackoverflow refer Writing files in Node.js

Generate and download archive zip with java

I have a zip file download function.
This function generates the .zip files on output folder in the server and downloads it.
Everything works perfectly!
However, testing with multi-users doens't work.
If 3 users attempt to generate the file at the same time, only one response is returned with the file for download.
The other 2 users are waiting forever and there is no result (no error occurs, the ajax call never returns).
My code:
JavaScript:
$.fileDownload('\GenereteZipAction', {
httpMethod: "POST",
data: $('#formZip').serialize()
}).done(function () {
alert('Download successfully.');
$('#modalZipLoading').modal('hide');
})
.fail(function () {
alert('Error');
$('#modalZipLoading').modal('hide');
});
Java:
//get the name of user
userName = request.getParameter("user");
//get real path
String realPath = getServletContext().getRealPath("/");
//create user folder
File fileOutput = new File(realPath+"/reports/output/"+userName);
fileOutput.mkdirs();
//generete reports in the user output folder
ReportHelper helper = new ReportHelper();
helper.genereteReports(fileOutput);
//set the reponse and...
response.setContentType("application/zip");
response.addHeader("Content-Disposition", "attachment;filename=Relatorios.zip");
//set the cookie for $.fileDownload go to done function
response.setHeader("Set-Cookie", "fileDownload=true; path=/");
//zip output user folder
ZipHelper zipHelper = new ZipHelper ();
zipHelper.zipAllfiles(fileOutput);
//create and fill ZipOutputStream
ZipOutputStream zip = new ZipOutputStream(response.getOutputStream());
zipHelper.fillZipOutputStream(zip);
//do download
zip.flush();
//close
zip.close();
//delete folder
deleteDir(fileOutput);
My system is for more than five thousand users, so I'm sure more than two will use the report generation function at the same time.
I do not have much information of aplication server, just know it is IBM WebSphere.
I do not know if the problem is in my code, or the server that
not allowing multi-users. Every help is welcome!!!
You are most likely running into thread safety issues. This may help you: https://www.quora.com/What-does-the-term-thread-safe-mean-in-Java
ReportHelper or ZipHelper could be not thread-safe. genereteReports looks to be modifying something on the file system. I would look carefully at the code and ask yourself on each line, "what happens if something else tries to execute while my first thread is executing this line?" I would suggest looking into synchronized calls and how they work.

IPC on Terminal Server with C/C++ an nw.js/node.js/node-native-module (C++)?

I have a Win32-DLL (C++) which is loaded as a plugin in another application. The DLL starts a nw.js instance (ShellExecuteEx and SEE_MASK_NOCLOSEPROCESS) and ends it at DLL unloading (by the hInstance of ShellExecuteEx). I need a way to send a string (plain ansi) to the nw-process and retrieve an answer (also string). The old way was a simple http-request with the response in the body. But the environment changes during the development, the "package" app-dll-nw runs multiple times by the same user and multiple users run on the same machine (terminal server). So port listing is "impossible" (yeah random ports or singleton nw, but no).
I found different ways:
socket - port listing problem
wm_copydata/wm_... - need a custom nw-plugin with hidden window (no native nw way); no request-response-system
RPC - port listing problem
DDE - no native javascript way (found a module, which uses .net); In my old delphi days DDE was a not so simple task and it failed multiple times with no logic.
shared memory - no experience; expectations: asynchronous, trigger?, no native javascript way
shared file - no experience; expectations: asynchronous, trigger (watcher on file change) but problems with synchronization, native js way possible
named pipe - no experience; expectations: win32-api and like a chat system (in-pipe [send broadcast] and out-pipe [receive broadcast], or both in one)? If yes, I can use one name about all instances and use unique identifiers and wait for the right answer.
What is a nice and simple way to communicate like the http-way but w/o networking?
Update 1: The node module "net" is able to create a server for a named pipe. The first test, sending a string from the dll to nw, was successful.
var server = net.createServer(function(stream) {
stream.on('data', function(c) {
console.log('data:', c.toString());
});
stream.on('end', function() {
//server.close();
});
});
server.listen('\\\\.\\pipe\\MyAppDynamicGUID');
Update 2 - My Solution
With named pipe and a simplified version of https://msdn.microsoft.com/en-us/library/windows/desktop/aa365592(v=vs.85).aspx I found a working methode.
Server in nw.js:
var server = net.createServer(function(req) {
req.on('data', function(c) {
console.log(c.toString());
req.write('123|Hello World', 'ascii');
});
});
server.listen('\\\\.\\pipe\\MyAppDynamicGUID');
The client in C++ (no permanent connection, strange string handling, simplified error handling):
static std::string PipenameA = "\\\\.\\pipe\\MyAppDynamicGUID";
#define BUFSIZE 512
std::string SendPipeRequestA(std::string sRequest) {
DWORD dwToWrite, dwWritten, dwRead;
BOOL bSuccess;
char chBuf[BUFSIZE];
std::vector<char> buffer;
HANDLE hPipe = CreateFileA(PipenameA.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hPipe == INVALID_HANDLE_VALUE)
return "-1|Pipe-Error 1 (connect)";
dwToWrite = (lstrlenA(sRequest.c_str())+1)*sizeof(char);
bSuccess = WriteFile(hPipe, sRequest.c_str(), dwToWrite, &dwWritten, NULL);
if (!bSuccess)
return "-1|Pipe-Error 2 (write)";
do {
bSuccess = ReadFile(hPipe, chBuf, BUFSIZE*sizeof(char), &dwRead, NULL);
if (!bSuccess && GetLastError() != ERROR_MORE_DATA)
break;
buffer.insert(buffer.end(), chBuf, chBuf + dwRead);
} while (!bSuccess);
std::string sResponse(&buffer[0]);
CloseHandle(hPipe);
return sResponse.c_str();
}
// Jonny
The answers you will get will be opinion based, be aware of that.
you can inject the data into the JS module as command line argument
for example
start nw.js MyData
and get it insinde the JS with process.argv.
now, sending the data back to the C++ executables/DLLs is a bit tricky.
if you shell-execute the process, you can have the handle to it.
you can print the data into the stdout from the JS part , and read it in the native app by getting the STDOUT handle from the process handle.
Register your nw.js app with a custom url should be an elegant way.
Such as "github://", "thunder://", "twitter://"
On windows you may have a look at:
https://msdn.microsoft.com/en-us/library/aa767914(v=vs.85).aspx
With custom url you can take simple arguments to nw.js at single-instance mode. See:
https://github.com/nwjs/nw.js/wiki/Handling-files-and-arguments#open-file-with-existing-app
If more data required maybe base64 can help, or even more by LZ-String compress method.

Deconstruct/decode Websocket frames like Google Chrome does

I'm connecting to a website via websocket connection (client to server), I know how to encode the data and write it to the server (using the net module in node.js) but when I'm reading the data back I get odd characters in front of the important data, like if I'm suppose to get:
// Data needed on the left and data I'm receiving from websocket on the right
'inited\r\n' -> '�inited\r\n'
'n:2\r\n' -> '�n:2\r\n'
This is how I am getting the data from the server
Klass.prototype.connect = function(){
// this.port is equal to 8080 and the exact server varys, but it's not that important anyways since the problem is decoding the data properly.
var that = this;
var buffer = "";
this.socket = new net.createConnection(this.port, this.server);
this.socket
.on("connect", function(){
that.sendHandshake(); // just sends a standard client to server handshake
})
.on("data", function(recv){
// .split('\r\n\r\n').join('\r\n') needed to separate the server handshake from the data I am trying to parse
buffer += recv.toString('utf-8').split('\r\n\r\n').join('\r\n');
while (buffer){
var offset = buffer.indexOf('\r\n');
if (offset < 0)
return;
var msg = buffer.slice(0, offset);
// parseMsg(msg)
buffer = buffer.slice(offset + 3);
}
});
};
I am probably doing a lot of things improperly in the code above, but I'm not quite sure how to do it exactly so that is the best I got for now.
Problem is I don't know how to remove the mystery/special characters. Sometimes there is only 1 mystery/special character, but other times there is multiple ones depending on the data but they are never after the important data I need to check.
When I use Google Chrome and view the data on through tools->JavaScript console->network tab and find the websocket stream I'm looking for Google parses it correctly. I know it's possible since Google Chrome shows the correct frames, how do I deconstruct/decode the data so I can view the correct frames on the terminal?
I don't really need it in a particular language as long as it works I should be able to port it, but I would prefer examples/answers in node.js since that is the programming language I am using to connect to the server.

Categories

Resources