Can I use Socket.IO with Django? [closed] - django

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
Is there any way to use Socket.IO http://socket.io/ with Django?

Sure you can!
Django itself arent asyncronous so you have to use a Socket.IO server in parallel with your normal django server, node.js isnt always a good choice but there exists others written in pure python.
here is a blog/tutorial that uses gevent as socket.io server.
http://codysoyland.com/2011/feb/6/evented-django-part-one-socketio-and-gevent/
For a similar solution that has a bit more history you can look at Orbited, (www.orbited.org)

I am asking does a server side django implementation exist for node.js in django.
No. node.js is its own language running in its own interpreter. However if you are asking if there is a Django app which allows communicating with a Socket.IO client, then yes and no. No because no pre-made solution currently exists, and yes because all the parts you need to implement it already exist.
To implement the protocol with django, check out Django-Websocket for the backend websocket server, Ajax libraries from Dajax Project and Socket.IO-rack which is a ruby gem which implements the protocol and ruby is close enough in structure to django that you can get a lot of inspiration from it.

Start here:
http://gevent-socketio.readthedocs.org
and here:
https://github.com/abourget/gevent-socketio
There are some Django examples as to how to get started.
It is based on Gevent, which implements a cooperative concurrency model. It's great coming from a request/response world, as it adds some callbacks and micro-threads without imposing it massively on your workflow.
Try it out :)

I think the best way to asyncronous communication with Django is have a node server listening in another port and use the api client of Socket.io. In this way, you aren't depend of the support of the modules for django and is very simple: Node listening the request from client, convert this request in a post request and send to Django for the port which listen Django.
Is the best way i think.
server.js
var http = require('http');
var server = http.createServer().listen(3000);
var io = require('socket.io').listen(server);
var querystring = require('querystring');
io.on('connection',function(socket) {
console.log('Connected to the client');
socket.on('new comment',function(data) {
console.log('Web--->Node');
var values = querystring.stringify(data);
console.log(values);
var options = {
hostname:'localhost',
port:'8000',
path:'/create-comment',
method:'POST',
headers:{
'Content-Type':'application/x-www-form-urlencoded',
'Content-Length':values.length
}
};
var request = http.request(options, function(response) {
response.setEncoding('utf8');
response.on('data',function(data){
//Here return django
console.log('Django-->Node');
io.emit('return comment',data);
});
});
request.write(values);
request.end();
});
});
views.py
def trysock(request):
print 'In tryshok'
comments = Comment.objects.all()
dic = {
'name': 'User',
'form': CommentForm(),
'comments': comments
}
return render(request,'index.html',dic)
#csrf_exempt
def create_comment(request):
print 'Django<---Node'
Comment.objects.create(
user = request.POST['user'],
comment = request.POST['comment']
)
response = JsonResponse({'user' : request.POST['user'], 'comment' : request.POST['comment']})
print response.content
return HttpResponse(response.content)
index.html
<div class='col-md-12'>
<div class='col-md-6'>
<form method='POST'>
{% csrf_token %}
{{form.comment}}
<button id='boton'>Comentar</button>
</form>
</div>
<div id='comentarios' class='col-md-6'>
{% for comment in comments %}
<p>{{ comment.user }} - {{ comment.comment}}</p>
{% endfor %}
</div>
</div>
<!-- Fin Formulario comentarios -->
</div>
<script>
var socket = io.connect('http://localhost:3000');
console.log(socket);
$('#boton').on('click', Comentar);
function Comentar(e) {
console.log('Comentar(e)')
e.preventDefault();
var datos = {
user:"user",
comment : 'comment'
};
socket.emit('nuevo comentario', datos);
console.log('Enviando....: ' + datos.user + '-' + datos.comment);
}
socket.on('devolviendo comentario', function(data) {
console.log('Recibiendo...');
var dato = JSON.parse(data);
$('#comentarios').prepend('<p>' + dato.user + '-' + dato.comment + '</p>')
});
</script>

For an example of using socket.io with django, you might want to look at django-serverpush. It integrates django with socket.io as the transport and tornado/tornandio2 as the async server instead of node.js
https://github.com/hamax/django-serverpush
Other have used django with node.js+socket.io with rabbitMQ as the message queue bridge between the two. There was a talk, "Real-Time Django" at djangocon 2011 which described usng this approach for large real-time (award-show-type) applications.

Guys there is no solid support for socket.io with django... there is how ever easy toy program support g-event socket.io support was dropped for the last year as well, django-socket.io is also abandoned.
If you want to build a simple toy program using django-socket.io and or g-event socket.io sure, but anything that scales is unlikely "https://github.com/ryesoft/gevent-socketio" this is experimental.
Issues with more than 1 worker with gunicorn....
https://github.com/abourget/gevent-socketio/issues/112
The work around is this commit.
https://github.com/getpenelope/gevent-socketio/commit/6c80c17705c9a1b3adcb0f99abde1c4d369c337b
I thought it would throw it out there just incase someone was trying to use this in a production environment like my self.

Related

Load a template with Django and React JS with a single GET call

I am building an application with Django as the backend and React js for making the interface of the application.
I have a set of Posts which I want to display.
Currently, the approach which I am following is -
Get the template having the compiled js code linked to it.
Then again make get call to get the posts
My question is - In this current approach I am making 2 GET calls to the backend, one for rendering the template and then again for getting the Post.
What is the best way to achieve this? Is this the usual flow how applications are built using Django and React JS?
First off: I don't see anything wrong with doing this in two requests, because one loads the application itself and the second loads the content. To me this seperation makes sense and might turn out to be useful in the future if you want to reuse say the Endpoint, that yields the the posts(i.e. the content).
Answering your question: If, for whatever reason, you absolutely want to load everything with a single GET, a good way of doing so, would be to pass a list of posts to the context as a JSON-serialized object and then load these into the JS-context within the Django-template.
i.e. in the view.py:
from json import dumps
def view(request):
context = {
'posts':get_posts(),
}
render_to_response('django_template.html', context,
context_instance=RequestContext(request))
def get_posts():
qs = Posts.objects.all()
return dumps({'posts': qs })
in the django_template:
{% block content %}
<div id="root"></div>
{% endblock %}
{% block javascript %}
<script>
var INITIAL_POSTS = {{ posts|safe }};
</script>
<script type="text/javascript"
src="PATH_TO_STATIC_REACT_ASSET.JS"></script>
{% endblock %}
you should now have your posts in your JS context and can load them in your React component. Once again: I would agree with Daniel Rosemans comment

User redirect with POST in iframe

I am building one of my first MVC 4 applications and I need some help with redirecting users.
I have a windows form application where I use a AxSHDocVw.AxWebBrowser to redirect the user to a specific URL , a SOAP web service to be precise, aswell as sending HTTP POST and HEADER data aswell.
This is done like so:
oHeaders = "Content-Type: application/x-www-form-urlencoded" + "\n" + "\r";
sPostData = "ExchangeSessionID=" + SessionID;
oPostData = ASCIIEncoding.ASCII.GetBytes(sPostData);
axWebBrowser2.Navigate2(ref oURL, ref o, ref o, ref oPostData, ref oHeaders);
I am looking to replicate this functionality in my MVC application, but am unsure of the how this can be done.
I was hoping to have this within an iframe, but can't find a way of sending the POST and HEADER data from this. This is what I have been trying so far:
Controller
ViewBag.URL = TempData["URL"];
ViewBag.SessionID = TempData["SessionID"];
ViewBag.FullURL = TempData["URL"] + "?ExchangeSessionID=" + TempData["SessionID"];
return View();
View
<iframe src="#ViewBag.FullURL" width="100%" height="500px"></iframe>
Basically I was trying to append the data to the end of the URL hoping this would work for the HTTP POST part. This is what I ended up with:
https://www.myurl.aspx?ExchangeSessionID=87689797
The user is being directed to the page, but the web service is giving me an error ( which tells me it is now receiving the POST data).
Can some please help me to try and fix this, or even give me advice on how to go about this another way. Like I said, I'm fairly new to MVC applications and I'm not entirely sure what I'm tryin to do is even possible.
Any help is appreciated. Thanks
I've decided to answer this question myself incase anybody is looking to do something similar in the future.
The first step was to create my iframe:
<iframe name="myframe" src="" width="100%" height="700px"></iframe>
Next I want to create a form with a button which, when pressed, will post the data to the url while targeting the iFrame (Note the target attribute of the form):
<form action="#ViewBag.URL" method="post" target="myframe">
<input type="hidden" name="ExchangeSessionID" value="#ViewBag.SessionID" />
<input type="submit" value="Submit" />
</form>
So what happens is, when the button is pressed, the form posts the ExchangeSessionID to the target URL and then the page response is displayed inside the iFrame.

How to block internet explorer on my Django web app?

I'm working on a web application that does not work well with Internet Explorer (web socket, json, security issues).
For now, before my application works with IE:
How can I refuse connections coming from Internet Explorer client ?
Thank you
Create a middleware where you're parsing the request.META['HTTP_USER_AGENT']. If you found that the user use IE, give him a nice message (e.g a notification or a little alert box) to says him that your site isn't optimized for his browser :)
Some code example: Django way
middleware.py (see the doc for more information)
class RequestMiddleware():
def process_request(self, request):
if request.META.has_key('HTTP_USER_AGENT'):
user_agent = request.META['HTTP_USER_AGENT'].lower()
if 'trident' in user_agent or 'msie' in user_agent:
request.is_IE = True
else:
request.is_IE = False
# or shortest way:
request.is_IE = ('trident' in user_agent) or ('msie' in user_agent)
your base template:
{% if request.is_IE %}<div class="alert">Watch out! You're using IE, but unfortunately, this website need HTML5 features...</div>{% endif %}
And then add it to your middlewares list.
Optimized: pure HTML way
If you only want to display a message like what I've done, you can use a HTML conditional comment:
<!--[if IE]> <div class="alert">...</div><![endif]-->
There is another way! Just use settings variable DISALLOWED_USER_AGENTS, and make sure that CommonMiddleware is installed on your site.
For example
import re
DISALLOWED_USER_AGENTS = (re.compile(r'msie\s*[2-7]', re.IGNORECASE), )
Cheers!

How can i send POST requests through ember

I have simple functions in my ember application that just do stuff like adding user vote to a post, or follow another user, and i was wondering how can I do this in ember?
I don't want to use this
jQuery.post('/posts/' + post.id + '/votes');

Django Socketio 101

I try to implement a chat with django-socketio in my django app.
First, I have to learn about django-socketio, so I read the README of https://github.com/stephenmcd/django-socketio
I really want to get the basis of it. So I try to create a simple thing where a message will be rendered through socketio.
My events.py:
#events.on_connect
def first_connect(request, socket, context):
socket.broadcast_channel("my message")
My view:
def chat(request):
return render_to_response('chat.html', {} ,context_instance=RequestContext(request))
My url:
url(r'^chat/$', 'projet.views.chat'),
My html:
<head>
{% load socketio_tags %}
{% socketio %}
<script>
var socket = new.io.Socket();
socket.connect();
socket.on('connect', function(){
socket.subscribe('my_channel');
});
</script>
</head>
When I go to localhost:8000/chat, nothing appear.
So it's probably very basic, but how can I do to simply send a message through my socket and render it in my html when I connect to it?
I really want to learn about it, so if someone has a tutorial about django-sockieto, I would really appreciate it.
You can look at Cody Soyland blog entries here and here. It may be outdated but I think you can get the feeling of what should be going on there. Also it's not about django-socketio.