Python SocketIO-client doesn't receive emits from nodeJS server - python

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!

Related

Python: Push Notifications to Node.js Socket.io using Redis PubSub

Now my project use Django as API and NodeJs (SocketIO) as server which require Realtime for pushing Notifications
I try pushing Notifications to Node.js Socket.io using Redis PubSub but not success. Please check out my code error:
My Python code. I publish to myChannel sample message:
def test_vew(request):
REDIS_SERVER = redis.Redis(host='localhost', port=6379, db=0)
REDIS_SERVER.publish("myChannel", "Demo Message")
return Response({ "success": True }, status=200)
My NodeJS Code:
var app = require('http').createServer()
const PORT = process.env.PORT || 3000;
var redis = require('redis').createClient();
const server = app.listen(3000, () => console.log('listening on port 3000'))
//sockets
const io = require('socket.io').listen(app)
redis.subscribe('myChannel', (message) => {
console.log(`Got message ` + message)
})
io.sockets.on("connection", function(socket) {
console.log("A User Connected to SocketIO");
redis.on("pmessage", function(pattern, channel, message) {
console.log(channel, message);
});
});
When I run function in Django, My NodeJS Socket Subcribe can't grab message (Nothing log in console). I don't know the reason.

django-channels websocket bridge error when trying to connect web socket

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

http post a base64 json request between Node.js and Python Flask server but Node received an incomplete json

I try to send a base64 json form node.js server to python flask server and than return a same base64 code back to node.js server. Flask can successfully receive my json but when it response to node and node try to print out the response. I got a error message say: "Unexpected end of JSON input". I found the reason is node server can not receive the base64 completely. It just only receive a small portion. What is the problem? Is post request has a string limit?
I tested when I change the base64 code to a short string. Node server can receive response normally.
Anyone can help me? Thank you.
This is my code:
<<< Node.js Server >>>
var express = require('express');
var http = require('http');
var app = express();
app.get('/', (req, res) => res.send('Hello World!'));
app.listen(10000, () => console.log('Running on http://localhost:10000'));
postData = JSON.stringify({
'code': <base64 code or short string here>
});
var options = {
hostname: 'localhost',
port: 10001,
path: '/test',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(postData)
}
};
var req = http.request(options, (res) => {
res.on('data', (chunk) => {
var data = JSON.parse(chunk);
console.log(data.message);
});
res.on('end', () => {
console.log('No more data in response.');
});
});
req.on('error', (e) => {
console.error(`problem with request: ${e.message}`);
});
req.write(postData);
req.end();
<<< Python Flask Server >>>
from flask import Flask
from flask import request
from flask import jsonify
app = Flask(__name__)
#app.route('/test', methods=['POST'])
def test():
request_data = request.get_json()
print(request_data['code'])
return jsonify(
message = request_data['code']
)
app.run(host='localhost', port=10001)
In NodeJS code, in data event, you will get chunk data(partial data), you need to wait until end event and then parse, following example may help you
var req = http.request(options, (res) => {
var data = '';
res.on('data', (chunk) => {
data += chunk.toString(); // buffer to string
});
res.on('end', () => {
data = JSON.parse(data);
console.log(data.message);
console.log('No more data in response.');
});
});

redis with nodejs+socketio and python, message event fired twice?

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")

Communicating Raspberry Pi with cloudfoundry

I have written a Node.js socket.io routine which will be called by a python socket io routine from my raspberry pi. It will communicate both ways. At the moment when I run these two routines on localhost it works fine. However when I deploy the server application to cloudfoundry and change the SocketIO connection link to cloudfoundry it does not work. Below is the client python
from socketIO_client import SocketIO
def on_updatepi_response(*args):
print 'updatepi'
def on_receivepi_response(*args):
print 'receiveepi'
with SocketIO('raspinode-server.cloudfoundry.com', 8080) as socketIO:
socketIO.on('receivepi', on_receivepi_response)
socketIO.on('updatepi', on_updatepi_response)
socketIO.emit('sendrabbit','testdata')
socketIO.wait(seconds=1)
I know cloudfoundry can be a bit strange as my first idea was to use rabbitmq but it is tied to the VCAP_SERVICES idea. However I did not think such a restriction would be there on a Node.js page.
Let me know if there is anything wrong with the above code and if not how can i get my external pi to send reading to my cloud app ?
Server Code is listed below though it is not relevant. It responds on localhost...I know the rabbitmq code is not hooked up yet
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var amqp = require('amqp');
var io = require('socket.io').listen(server)
function rabbitUrl() {
if (process.env.VCAP_SERVICES) {
conf = JSON.parse(process.env.VCAP_SERVICES);
return conf['rabbitmq-2.4'][0].credentials.url;
}
else {
return "amqp://localhost";
}
}
var port = process.env.VCAP_APP_PORT || 3000;
var messages = [];
function setup() {
var exchange = conn.exchange('cf-demo', {'type':'fanout', durable:false}, function(){
var queue = conn.queue('', {durable:false, exclusive:true},
function() {
queue.subscribe(function(msg) {
messages.push(htmlEscape(msg.body));
if (messages.length > 10) {
messages.shift();
}
});
queue.bind(exchange.name, '');
});
queue.on('queueBindOk', function() {httpServer(exchange);});
});
}
server.listen(8080);
io.sockets.on('connection', function(socket){
// when the client emits sendrabbit, this listens
socket.on('sendrabbit', function(data)
{
// we tell the client to execute updatepi with 2 parameters
io.sockets.emit('updatepi', socket.username, data)
});
socket.on('disconnect', function()
{
socket.broadcast.emit('updatepi', 'SERVER', socket.username + ' has disconnected');
});
});
It's my understanding that your server should listen on the port Cloud Foundry assigns it (available in an env var). You can't assume it will be 8080. Then the client talks to raspinode-server.cloudfoundry.com (no port) and Cloud Foundry routes it to the correct place.

Categories