I've set a nodejs server along with simple python script with redis-py.
I have this on my nodejs server:
var http = require('http');
var server=http.createServer(onRequest).listen(3000);
var io = require('socket.io')(server);
var redis = require('redis');
var fs= require('fs');
var sub = redis.createClient();
sub.subscribe('channel');
function onRequest(req,res){
var index;
fs.readFile('./index.html', function (err, data) {
if (err) {
throw err;
}
index = data;
res.writeHead(200,{'Content-Type':'text/html'});
res.write(index);
res.end();
});
};
var sockets=[];
io.on('connection', function(socket){
console.log('a user connected');
sockets.push(socket);
console.log(sockets.length);
sub.on('message', function(channel, message){
console.log(message);
sockets[0].emit('chat message',message);
});
io.emit('chat message', "enter nickname");
socket.on('disconnect', function(){
console.log('user disconnected');
});
});
This is just a simple test where I've tried to find out why my messages are sent multiple times.
I've figured that sub.on('message') is fired twice for each message that I send from python. Why?
The python code is pretty simple:
import redis
r=redis.StrictRedis()
pubsub=r.pubsub()
r.publish('channel',"HHHHHHH")
Related
So this is what I am trying to do, I want to be able to send a message in a browser towards a python script. I've got to the point where I can send a message in the browser and the server sees it. For testing purposes I used io.emit('input', data) to send the data towards my python script but nothing happens on the python side.
script.py:
import socketio
sio = socketio.Client()
#sio.event
def connect():
print('connected')
#sio.on("input")
def on_input(key):
print(key)
sio.connect('http://192.168.2.9:5000', namespaces=['/justin'])
server.js:
const express = require('express')
const app = express();
const http = require('http').createServer(app);
const io = require('socket.io')(http);
var justin = null;
app.use(express.static('public'));
io.of('/justin').on('connection', function(socket){
console.log('justin connected');
justin = socket;
});
io.on('connection', function(socket){
console.log('a user connected');
socket.on('event', (data) => {
io.emit('input', data)
})
socket.on('disconnect', () => {
//
})
});
http.listen(5000, function(){
console.log('listening on *:5000');
});
Is there something I'm not seeing or is this just not possible?
Thanks in advance!
I'm writing a simple web app to get a handle on how node child processes work. Basically you enter your name into an angular frontend which passes the name to an express backend in a javascript object. The backend passes the name as an argument to a simple python script as a command line argument using the child_process module. Theres nothing wrong with the front end and the name gets successfully passed to the backend but when I call stdout on the python process it doesn't work. There aren't any error messages.
Heres the express code:
app.post('/api', (req, res, next) => {
console.log(req.body.name);
const spawn = require('child_process').spawn;
const process = spawn('python3', ['./hello.py', req.body.name]);
process.stdout.on('data', (data) => {
console.log(data);
res.status(200).json({greeting: data});
});
});
I put two console.log statements in the code to debug it. The first one prints the data but the second one inside the stdout function isn't called at all. The python script is in the same folder as the app.js express file so I'm pretty sure theres nothing wrong with the file path.
Here's the python script:
import sys
print('hello' + sys.argv[1])
sys.stdout.flush()
When I run it in the command line it works exactly as expected but I included it anyway just in case.
Process.stdout.on will keep on streaming until the end event. The code is wrong because you are actually sending response for every time there is some value in stdout. And you cant set the response header more than once. Try writing the code in below way. Thanks
let output;
Process.stdout.on("data", (data) => {
output += data;
});
Process.on("end", () => {
// send response here
});
close will trigger when your data completes
app.get("/list-account", async (req, res) => {
try {
let array = "";
let response = await child.spawn(
path.join(__dirname, "xcv-alpha-keychain.exe"),
["listaccounts"]
);
await response.stdout.on("data", (data) => {
const stdout = data.toString();
console.log("stdout", stdout);
array += stdout;
// return res.status(200).json({ array });
});
response.stderr.on("data", (data) => {
return res.status(500).send(data.toString());
});
response.on("error", (error) => {
return res.status(500).send({ error });
});
response.on("close", (code) => {
return res.status(200).json({ array, code });
});
} catch (error) {
return res.status(500).send(["a", "b", "c"]);
}
});
Instead of
console.log(data)
use
console.log(data.toString())
Im trying to implement real time notifications in my django app.I have set up signals and consumers . Im getting an error in the javascript side
My javascript code:
<script>
document.addEventListener('DOMContentLoaded', function() {
const webSocketBridge = new channels.WebSocketBridge();
const nl = document.querySelector("#nl");
webSocketBridge.connect('student/dashboard/tasks/');
webSocketBridge.listen(function(action, stream) {
console.log("RESPONSE:", action);
if(action.event == "New Task") {
var el = document.createElement("li");
el.innerHTML = ` <b>${action.username}</b> completed Task
${action.title}`;
nl.appendChild(el);
}
})
document.ws = webSocketBridge; /* for debugging */
})
</script>
The error shows on the console :
TypeError: Invalid WebSocket constructor. Set
`options.constructor
I'm very new to nodejs what I try to do is upload an image with some data to nodejs API but before saving data to Mongo DB I try to do some process to this uploaded image using Python class then I will save the results to DB
so can I send uploaded image to python code and waite the result before saving any data to DB
my code is here
router.post('/img2text', upload.single('photo'), (req, res) => {
// Create the object for insertion into database
const Img2text = new img2text({
imgPath: req.file.path,
sender: req.body.sender,
processed: 0,
resultText: "no result",
});
/////////////////////////////////////////////////////////////start
var exec = require("child_process").exec;
exec(`python uploads/hello.py ${req.file.path}`,(error, stdout, stderr) => {
if (error) {
Img2text.processed=0;
Img2text.resultText='no result'
console.error(`exec error: ${error}`);
return;
}
console.log(`stdout: ${stdout}`);
Img2text.processed=1;
Img2text.resultText=stdout.toString('utf8');
console.log(`stderr: ${stderr}`);
console.log(req.query.firstname);
});
/////////////////////////////////////////////////////////end
// Save into database
Img2text.save((err) => {
// Check if error
if (err) {
res.json({ success: false, message: err });
} else {
console.log("img saved !!")
res.json({ success: true, message:img.resultText }); // Return success message
}
});
});
if the python code takes so long time my object will be empty?
any answer will be greatly appreciated
Have you tried to use Promise,If not refer this link Promise MDN. Just wrap your process in a Promise and when you finish with your process resolve it and save it to database.
router.post('/img2text', upload.single('photo'), (req, res) => {
// Receive your image
let pythonProcess = new Promise((resolve, reject)=>{
// do your process
reolve() // resolve with updated data
})
pythonProcess.then(img =>{
//save to db
})
})
Now In Your case best possible, I prefer is to use aync/await Async/await MDN. Do not take it as another way to do it, It is just modern way to use promise. As internally await also setup promise chain. You have both options, either you can go it through promises you will get handy to the one of the best thing of javascript or If you want small piece of code go with await.
router.post('/img2text', upload.single('photo'), async(req, res) => { // To use await function need to be a async function
// Create the object for insertion into database
const Img2text = new img2text({
imgPath: req.file.path,
sender: req.body.sender,
processed: 0,
resultText: "no result",
});
/////////////////////////////////////////////////////////////start
var exec = require("child_process").exec;
await exec(`python uploads/hello.py ${req.file.path}`,(error, stdout, stderr) => {
if (error) {
Img2text.processed=0;
Img2text.resultText='no result'
console.error(`exec error: ${error}`);
return;
}
console.log(`stdout: ${stdout}`);
Img2text.processed=1;
Img2text.resultText=stdout.toString('utf8');
console.log(`stderr: ${stderr}`);
console.log(req.query.firstname);
});
/////////////////////////////////////////////////////////end
// Save into database
Img2text.save((err) => {
// Check if error
if (err) {
res.json({ success: false, message: err });
} else {
console.log("img saved !!")
res.json({ success: true, message:img.resultText }); // Return success message
}
});
});
With below code I have created a HTTP server on port 3000 and have added some get parameters. I want to invoke a python script with this express.js server code such that when I hit localhost:3000/key1/abc/key2/234 python script will get invoked. I've my python script ready which takes input args as sys.argv. Please suggest how to call python script with this code so that it will take value1 and value 2 as input arguments and return json.
var express = require('express');
var app = express();
app.get('/key1/:value1/key2/:value2',function(req,res)
{
console.log(req.params);
var value1 = req.params.value1;
var value2 = req.params.value2;
res.send(req.params);
});
app.listen(3000,function()
{
console.log("Server listening on port 3000");
});
To run a Python script from Node.js would require spawning a new process.
You can do that with child_process.
You would run python as the executable and give your script name as the first argument.
Here is an example based on the documentation linked above:
const spawn = require('child_process').spawn;
const ls = spawn('python', ['script.py', 'arg1', 'arg2']);
ls.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
ls.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
});
ls.on('close', (code) => {
console.log(`child process exited with code ${code}`);
});
If you want to execute it with params
const scriptExecution = spawn(pythonExecutable, ["my_Script.py", "Argument 1","Argument 2"]);