I have node server:
var http = require('http');
var server = http.createServer().listen(4000);
var io = require('socket.io').listen(server);
var cookie_reader = require('cookie');
var querystring = require('querystring');
var redis = require('redis');
var sub = redis.createClient();
//Subscribe to the Redis chat channel
sub.subscribe('chat');
//Configure socket.io to store cookie set by Django
io.use(function(){
io.set('authorization', function(data, accept){
if(data.headers.cookie){
data.cookie = cookie_reader.parse(data.headers.cookie);
return accept(null, true);
}
return accept('error', false);
});
io.set('log level', 1);
});
io.sockets.on('connection', function (socket) {
//Grab message from Redis and send to client
sub.on('message', function(channel, message){
socket.send(message);
});
//Client is sending message through socket.io
socket.on('send_message', function (message) {
values = querystring.stringify({
comment: message,
sessionid: socket.handshake.cookie['sessionid'],
});
var options = {
host: 'localhost',
port: 8000,
path: '/node_api',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': values.length
}
};
//Send message to Django server
var req = http.request(options, function(res){
res.setEncoding('utf8');
//Print out error message
res.on('data', function(message){
if(message != 'Everything worked :)'){
console.log('Message: ' + message);
}
});
});
req.write(values);
req.end();
});
});
When I send message it does not save in the database..
Here is my view for django:
#csrf_exempt
def node_api(request):
print "inside node"
try:
print "inside try"
session = Session.objects.get(session_key=request.POST.get("sessionid"))
print "first"
user_id = session.get_decode().get("_auth_user_id")
print user_id
user = User.objects.get(id=user_id)
Comments.objects.create(user=user, text=request.POST.get("comment"))
r = redis.StrictRedis(host="localhost", port=6379, db=0)
r.publish("chat", user.username + ": " + request.POST.get("comment"))
return HttpResponse("Everything worked :")
except Exception, e:
return HttpResponseServerError(str(e))
Whats wrong in here??
Can anyone guide me to right direction?
When I go to '/node_api/' url it says Session matching query doesnot exist..
My view for displaying message:
#login_required
def home(request):
print "entered"
comments = Comments.objects.select_related().all()[0:100]
return render(request, "index.html", locals())
When I submit the message its not saving to database neither displaying...
Thanx in advance??
If you are using python then why don't you try python way of doing realtime.
Try tornado with django. It supports socket.io..
You can code in python with no difficulty.
It doesn't mean javascript is not good but try do in python and have a look at tornado, redis, django. YOu will find your solution.
Related
I am facing a situation where I am able to set a session with Flask and verify the session exists when visiting the Python endpoints directly. When I make my frontend return the session status, the Python endpoint returns not logged in.
Python:
#app.route("/status")
def status():
try:
session["access_token"]
result = {
"rc": "loggedin",
"msg": f"User is logged in with access token {session['access_token']}."
}
except:
print("No access token found")
result = {
"rc": "notloggedin",
"msg": "User is not logged in."
}
return jsonify(result)
#app.route("/login")
def login():
return redirect(OAUTH_URL)
#app.route("/logout")
def logout():
try:
session.pop("access_token")
print(f"Ended session.")
except:
print("No session to end.")
return redirect(f"https://{HOME_URL}")
#app.route("/oauth/callback")
def oauth_callback():
print(REDIRECT_URI)
code = request.args["code"]
access_token = client.oauth.get_access_token(
code, redirect_uri=REDIRECT_URI
).access_token
session["access_token"] = access_token
Jquery:
$.ajax({
method: "GET",
cache: false,
url: "https://account.mydomain.net/status",
xhrFields: {
withCredentials: true
}
}).done(function( msg ) {
console.log( msg );
});
When calling the Python endpoints directly, it all works. I got to /login, am redirected to the Oauth provider and then returned to my home page. When I then go to /status, it returns:
{"msg":"User is logged in with access token REDACTED.","rc":"loggedin"}
When the Ajax function calls the endpoint (same browser, same URL as the endpoint I am hitting)
{"msg":"User is not logged in.","rc":"notloggedin"}
I saw some similar issues, but none that covered this. I expect my Flask session to stay alive, but it does not. Perhaps I am misunderstanding how this works. Don't mind all the print(), this is mostly for debugging this frustrating issue. The Python endpoint is on account.domain.net and the app calling it is on the apex domain.net. CORS is configured properly, since it is returning a value.
I checked both domains, the session cookie is set the same for both.
I didn't get this to work with Jquery, but native JS fetch:
app.config['SESSION_COOKIE_DOMAIN'] = ".domain.net"
app.config["SESSION_COOKIE_NAME"] = "domain-session"
app.config["REMEMBER_COOKIE_DOMAIN"] = "None"
async function postData(url = '') {
// Default options are marked with *
const response = await fetch(url, {
method: 'GET', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, *cors, same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'include', // include, *same-origin, omit
headers: {
'Content-Type': 'application/json'
// 'Content-Type': 'application/x-www-form-urlencoded',
},
redirect: 'follow', // manual, *follow, error
referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
});
return response.json(); // parses JSON response into native JavaScript objects
}
This is my first time with using jquery and I am trying to save a reply but it gives a successful message but it not actually but I can't see the reply that the system says it saved.
$(document).ready(function(){
$(".reply_open_modal").click(function(){
var id=$(this).parents("tr").children("td:eq(0)").text();
var name=$(this).parents("tr").children("td:eq(2)").text();
$("#reply_id").val(id);
$("#reply_name").text(name);
});
I think this part of my system works but iIam not sure and the purpose of this code is to send the reply message
$(document).on("click","#reply_btn",function(){
$(this).attr("disabled","disabled")
$(this).text("Sending Reply")
var id=$("#reply_id").val();
var message=$("#reply_message").val();
$.ajax({
url:'{% url 'admin_message_replied' %}',
type:'POST',
data:{id:id,message:message},
})
.done(function(response){
if(response=="True"){
alert("Sent")
}
else{
alert("Not Sent")
}
location.reload()
})
.fail(function(){
alert("Error in Sending Reply")
})
})
})
This is the function that saves the reply into my database but it not working:
#csrf_exempt
def admin_message_replied(request):
reply_id=request.POST.get("id")
reply_message=request.POST.get("message")
try:
messages = SendmessageAdmin.objects.get(id=reply_id)
messages.message_reply = reply_message
messages.save()
return HttpResponse("True")
except:
return HttpResponse("False")
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 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.');
});
});
I need to create an application, where GAE server will always talk with just one client (i.e. one message should be always sent just to one client).
I do the following -
Python:
def get(self):
# generate token, when page is loaded
client_id = uuid.uuid4().hex
token = channel.create_channel(client_id)
template_values = {'token': token,
'client_id': client_id
}
self.response.out.write(template.render('page.html', template_values))
def post(self):
# reply to the client
...
client_id = self.request.get('id')
channel.send_message(client_id, message)
Javascript:
sendMessage = function(field) {
$.ajax({
type: "POST",
url: "/",
data: "f=" + field + "&id=" + "{{ client_id }}", // WARNING!
contentType: "application/x-www-form-urlencoded",
success: function(data) {
}
});
};
onOpened = function() {
connected = true;
sendMessage('opened');
};
onMessage = function(msg) {
alert(msg.data);
};
onError = function(err) {
alert(err);
};
onClose = function() {
alert("close");
};
// open new session
channel = new goog.appengine.Channel('{{ token }}'); // WARNING!
socket = channel.open();
socket.onopen = onOpened;
socket.onmessage = onMessage;
socket.onerror = onError;
socket.onclose = onClose;
It works well, but with such scenario both token and client_id are passed to the client. Is it OK?
There's no technical reason not to do this. If you're worried about security, the token is far more valuable: an attacker who could listen to your traffic could take the token and listen to channel messages in a different context. The clientid wouldn't let them do that.
But I do have a question: why not return the message in the POST response, rather than sending a message over the channel? Or is the sample code just simplified for the example?