zeromq ROUTER,DEALER message encoding format - python

I have written an application which is nodejs (main app) and python (client) app that i want to communicate with each other using zmq Router,Dealer pattern.
the problem is i could not read the messages sent from clients to nodejs (router) app.
its encoded some how.
the code is as simple as below:
var responder = zmq.socket('router');
responder.on('message', function(request) {
console.log(request);
// i could not read the messages here.its obfuscated
});
responder.bind('tcp://127.0.0.1:8000', function(err) {
if (err) {
console.log(err);
} else {
console.log('Listening on 8000...');
}
});
python:
socket = context.socket(zmq.DEALER)
socket.connect("tcp://127.0.0.1:8000")
socket.send('blaaaa')
print 'message sent!'

If you wish to use the DEALER/ROUTER sockets, then the message is actually given as the second argument for the callback function.
var responder = zmq.socket('router');
responder.on('message', function(header, body) {
console.log(body.toString('utf8'));
});
The message is in the format of a Buffer, but you can turn it into a string using .toString(encoding);
The header contains an identity, this allows you to later route the response/answer back to the correct sender/requester that made the original request.

For your application, PUSH-PULL seems more appropriate:
var zmq = require('zmq');
var responder = zmq.socket('pull');
responder.on('message', function(request) {
console.log(request.toString());
// Use `toString` to convert Buffer to string
});
responder.bind('tcp://127.0.0.1:8000', function(err) {
if (err) {
console.log(err);
} else {
console.log('Listening on 8000...');
}
});
import zmq
context = zmq.Context()
socket = context.socket(zmq.PUSH)
socket.connect("tcp://127.0.0.1:8000")
socket.send('blaaaa')
print 'message sent!'

Related

How to fetch data analyzed in python to node.js and pass it to angular?

I am new to angular and i want to display JSON data from python to angular with the help of node.js and I used child process to connect python and node.js but I dont know how to pass it to angular service
node.js file
const express = require('express')
const { spawn } = require('child_process')
const app = express()
const port = 8000
app.get('/', (req, res) => {
let dataToSend
let largeDataSet = []
// spawn new child process to call the python script
const python = spawn('python', ['test.py'])
// collect data from script
python.stdout.on('data', function (data) {
console.log('Pipe data from python script ...')
//dataToSend = data;
largeDataSet.push(data)
})
// in close event we are sure that stream is from child process is closed
python.on('close', (code) => {
console.log(`child process close all stdio with code ${code}`)
// send data to browser
res.send(largeDataSet.join(''))
})
})
app.listen(port, () => {
console.log(`App listening on port ${port}!`)
})
Technically you just have to send a Http GET request from your service.
I suggest that you should read and follow this offical http client guide to set it up correctly.
Here is a simple service snippet. This should be enough.
#Injectable({
providedIn: 'root',
})
export class MyService {
constructor(private http: HttpClient) {}
getData(): Observable<any> {
const url = '';
return this.http.get(url);
}
}

tRPC Mutation Wait For Data Updated

I'm using tRPC, NextJS, and PyShell for my project. I'll send user input to trpc and use that info as input to python script. Wait for python file done and return updated data to trpc, then send back to frontend.
Currently, it takes longer for python file to finish, and trpc does not send back the right info to frontend. Is there a way to fix that?
The code below is for trpc:
.mutation("upload", {
// validate input with Zod
input: z.object({ input: z.string() }).nullish(),
async resolve({ input }) {
var msg = ""
if (input?.input) {
console.log("-----------------------")
pyshell.on('message', async function (message) {
console.log("MSG: ", message);
msg = message;
});
pyshell.send(['sent', input.input]).end( function (err) {
if (err) console.error(err);
console.log("done");
});
}
return msg.length != 0;
},
});
msg is supposed to get updated with info from print statement in python file. It shows empty string in msg now.

How to receive data from server using Kotlin?

I have a server written in python and an Android client written in Kotlin (in Android Studio IDE). I use sockets for maintaining this connection. After the client sends a message to the server, the server will need to send an answer to the client. I didn't find a way to receive data at the client by using sockets. I tried to do that:
var server = Socket(serverIP, serverPort)
server.outputStream.write(message.toByteArray())
var answer = server.inputStream.bufferedReader().use(BufferedReader::readText)
server.close()
but it seems not to work. If it matters, the sending at server side looks like that:
client.send(message.encode())
I suppose, you are using OkHttp for this. In my app I have the following code
private fun getClient(): OkHttpClient {
return try {
val builder = OkHttpClient.Builder()
builder.pingInterval(30, TimeUnit.SECONDS)
builder.build()
} catch (e: Exception) {
throw RuntimeException(e)
}
}
class WebSocketController(
val callback: SomeCallback
) {
private val url = "wss://your.url.com/"
private val socketClient = getClient()
private var serverSocket: WebSocket? = null
private val listener = object : WebSocketListener() {
override fun onOpen(webSocket: WebSocket, response: Response) {
super.onOpen(webSocket, response)
val json = "" // your payload to send on connect
serverSocket = webSocket
serverSocket!!.send(json)
}
override fun onMessage(webSocket: WebSocket, text: String) {
super.onMessage(webSocket, text)
val data = Json.decodeFromString<YourModel>(text)
// here you can use your data from server
callback.makeSomething(data)
}
override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
super.onFailure(webSocket, t, response)
callback.onFailure(t)
}
}
fun establishConnection() {
socketClient.newWebSocket(requestBuilder().build(), listener)
}
fun disconnect() {
val json = "" // your payload on disconnect
serverSocket?.send(json)
}
private fun requestBuilder(): Request.Builder = Request.Builder().url(url)
}

Real time notifications with Django and Socket.io

currently i'm implementing real time notifications for my Django project.
I'm following instructions from this tutorial. Problem is, i'm using Socket.io 1.4.5 and tutorial is written for pre-1.0 versions. So i had to adapt some code following 'Migrating from 0.9' guideline on Socket.io site. What i got is:
var http = require('http');
var server = http.createServer().listen(8002);
var io = require('socket.io')(server);
var cookie_reader = require('cookie');
var querystring = require('querystring');
var redis = require('redis');
// Supposedly this should store cookie set by Django
io.use(function(socket,accept){
var data = socket.request;
if(data.headers.cookie){
data.cookie = cookie_reader.parse(data.headers.cookie);
return accept(null, true);
}
return accept('error', false);
});
io.sockets.on('connection', function (socket) {
// Redis client
client = redis.createClient();
// Subscribe to notification channel
client.subscribe('notifications.' + socket.handshake.cookie['sessionid']);
console.log('subscribed');
//Grab message from Redis and send to client
client.on('message', function(channel, message){
console.log('on message', message);
socket.send(message);
});
// Unsubscribe
socket.on('disconnect', function() {
client.unsubscribe('notifications.' + socket.handshake.cookie['sessionid']);
});
});
When i'm running this script:
node notifications.js
After 2 seconds of silence i get this error:
client.subscribe('notifications.' + socket.handshake.cookie['sessionid']);
^
TypeError: Cannot read property 'sessionid' of undefined
at Namespace.<anonymous> (path/to/notifications.js)
at Namespace.emit (events.js:107:17)
at Namespace.emit (/path/to/node_modules/socket.io/lib/namespace.js:206:10)
at /path/to/node_modules/socket.io/lib/namespace.js:174:14
at process._tickCallback (node.js:355:11)
Can somebody point me to what i did wrong?
Just found what my mistake was.
To access cookie, instead of socket.handshake i should be using socket.request. So my current code looks like this now:
var http = require('http');
var server = http.createServer().listen(8002);
var io = require('socket.io')(server);
var cookie_reader = require('cookie');
var querystring = require('querystring');
var redis = require('redis');
io.use(function(socket,accept){
var data = socket.request;
if(data.headers.cookie){
data.cookie = cookie_reader.parse(data.headers.cookie);
return accept(null, true);
}
return accept('error', false);
});
io.on('connection', function (socket) {
// Redis client
client = redis.createClient();
// Subscribe to notification channel
client.subscribe('notifications.' + socket.request.cookie['sessionid']);
console.log('subscribed');
//Grab message from Redis and send to client
client.on('message', function(channel, message){
console.log('on message', message);
socket.send(message);
});
// Unsubscribe
socket.on('disconnect', function() {
client.unsubscribe('notifications.' + socket.request.cookie['sessionid']);
});
});

Emitting messages from python-shell to a browser in a Node Express App

I have an express app and I would like to be able to trigger python scripts via routes and emit the log into the browser.
I have created a route which triggers the python scripts correctly and outputs the log into the node console using python-shell module. How can I push this log to the browser in real time.
I have a button on an index.html page which triggers an Ajax post request to a /python route below. I have tried to implement this with socket.io but haven't managed to get my head around it. Is socket.io the way forward, please point me in the right direction or can someone recommend an alternative?
My file layout is:
server.js
var express = require('express');
var path = require('path');
var app = express();
var port = process.env.PORT || 3000;
var http = require('http');
var server = http.createServer(app);
var io = require('socket.io').listen(server);
/* A bit inbetween */
server.listen(port)
app/routes.js
var PythonShell = require('python-shell');
var config = require('../config/config');
module.exports = function(app) {
app.get('/', function(req, res) {
res.render('pages/index.ejs', {
pageTitle: 'Index'
}); // load the index.ejs file
});
app.post('/test', function(req, res) {
var options = {
mode: 'text',
pythonPath: config.pythonPath,
pythonOptions: ['-u'],
scriptPath: config.pythonScriptsDirectory
};
var pyshell = new PythonShell('printRange.py', options);
pyshell.on('message', function (message) {
console.log(message);
});
res.sendStatus(200)
});
}
Thanks in advance
socket.io is a good solution. This will take care of passing the messages from the server to the client. You just post the message to on the server side, and have a callback react to it on the client side
On the server side you'll have something like this:
var app = require('express')();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
io.on('connection', function(){
console.log('connected');
});
server.listen(3000);
...
var pyshell = new PythonShell('printRange.py', options);
pyshell.on('message', function (message) {
if (connected)
io.emit('logentry',message);
});
On the client side, you'll have something like this:
<script src='/socket.io/socket.io.js'></script>
<script>
var socket = io();
socket.on('logentry',function(log_entry){
add_to_html(log_entry); // You need to implement this function.
});
</script>

Categories

Resources