Extend Django's real-time processing capabilities with node. JS and Socket.io

Source: Internet
Author: User
Tags django server install django node server pip install django install redis redis server
Today, our goal is to use Django,redis, and Socket.io to build a real-time chat room. Although almost all Web applications can be built in a chat room. This article will tell you at a high level how to transform a rest-based application into a real-time web application. I'll use Django to create rest parts, and actually freely use any of your comfortable language/frameworks. Next, let's jump into the code and first enumerate the parts we need.

Composition

    • Django 1.4+
    • Redis 2.6.x (version optional, but recommended)
    • Redis-py 2.7.x (required only if you are using Redis)
    • node. js v0.8.x
    • Socket.io v0.9.x
    • Cookie v0.0.5
    • Database, SQLite, and others you think are similar to the database format can be


The version you are using may be different from me, I have not tested the other versions for the time being, all using the most current stable version. If you cannot install it by the following method, I have compiled the Ubuntu software package. You can get other operating system versions from the comments.

#https://docs.djangoproject.com/en/dev/topics/install/sudo apt-get install python-pipsudo pip install Django #http:// Redis.io/downloadsudo apt-get Install redis-server #https://github.com/andymccurdy/redis-pysudo pip Install Redis     #https://github.com/joyent/node/wiki/installing-node.js-via-package-managersudo apt-get Install Python-software-propertiessudo add-apt-repository ppa:chris-lea/node.jssudo apt-get updatesudo apt-get Install Nodejs #https://github.com/learnboost/socket.ionpm Install Socket.io #https://github.com/shtylman/node-cookienpm Install Cookies

Let's start with Django project

django-admin.py startproject realtime_tutorial && cd realtime_tutorialpython manage.py Startapp coremkdir Nodejs

After executing the above code, Django Project is configured, and the next step is to set up the database in the settings file. Create a blank database first. (This is an example of a settings file.) Added a "core" to my app and then configured the path to templates and URLs. You can change the configuration information in the settings as you like, but it should correspond to your app.

Model

Models is simple, we are going to build a table with user and text. If you want to make him more complicated, you can add information such as chatroom. (For the sake of simplicity, only two are written here)

From django.db import modelsfrom django.contrib.auth.models Import User class Comments (models. Model):  user = models. ForeignKey (User)  text = models. Charfield (max_length=255)

This is the model we are going to use, and then execute the following SYNCDB code (the first line of code) to create the database. Then create several user to test. (second line of code)

Python manage.py syncdbpython manage.py createsuperuser Node Server with Socket.io

This section will describe the delivery and acquisition of real-time information. Use node. js to create an app server that relies on Socket.io, using Redis to do this chore. In the Nodejs dictionary, create a file called "Chat.js" and put it here:

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 (' Socket.io/node_modules/redis '); var sub = redis.createclient (); Subscribe to chat channelsub.subscribe (' chat '); Configure Socket.io to store Django settings for cookieio.configure (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) {//) send information from Redis to client sub.on (' message ', function (channel, message) {so  Cket.send (message);     }); The client sends a message via Socket.io socket.on (' Send_message ', function (message) {values = Querystring.stringify ({comment:mes         Sage, sessionid:socket.handshake.cookie[' SessionID '],}); var options = {host: ' LocalHost ', port:3000, Path: '/node_api ', Method: ' POST ', headers: {' content-type ': ' application/x         -www-form-urlencoded ', ' content-length ': Values.length}};             Use Django server to send a message var req = http.get (options, function (res) {res.setencoding (' utf8 '); Output error message Res.on (' Data ', function (message) {if (Message! = ' everything worked:) ') {console.log (' Messag        E: ' + message ');    }      });         });    Req.write (values);  Req.end (); });});

First, we import and create an HTTP server to listen on the localhost 4000 port. Then subscribe to the "chat" Chanel of Redis. Finally, as long as we call it in Django view.


The last time we set up the Django setting where Socket.io can use cookies in the local domain, this allows us to access cookie data through Socket.handshake.cookie. How we can get the user's session.

We can only hold a lot of events after we set up Socket.io cookies, the first event is the Redis publishing channel, when our users notice that a new message has been notified that it will send a message to all the site's clients.

Another event is when the client sends a message via Socket.io, we use the string query (queryString) module to create a query to be sent to our Django service. Our Django service will run on local Port 3000 but you can change that demand. The path is set to/node_api that URL we will soon create next to Django. Once we send querystring we wait for Django to save the relevant components and return to us "everything worked (all working)". Shut down the node console if we don't get the output error returned to us


A node that does not use Redis

You really have absolutely no need to use Redis for this project, I find it will be a good learning experience, if you want to shunt Redis you can create a channel, use an expression or some other class library, where the code will receive a message from Django when a comment is saved Then you can add comments to all the clients via Socket.io
Template

This is where all of our HTML and JavaScript are placed, allowing us to show comments and interact with our node service

Realtime Django 
 
       
 
  
  
    {% for comment in comments%}
  • {{Comment.user}}: {{comment.text}}
  • {% ENDFOR%}


On top we use sockets. IO is connected to our node service on local port 4000. When we get a message from the server, we do some escaping in the directory and add it to our comment list, and when we want to send a message we do a button check for the corresponding 13 (press the next key) in the input box. Once that is pressed we send a message to the server so that it is held. Once it's been saved to our database by Django, we get a "message" event to add it to our session list.

Our Django shows that we will load a "comments" variable in the next step, so we set and iterate through all the loops below. This part is only used when the page is initially loaded, and our JavaScript will add data to this directory as a new data from our node service

View

Open realtime_tutorial/core/views.py and edit as I do:

From core.models import Comments, User from django.shortcuts import renderfrom django.http import HttpResponse, Httprespon Seservererrorfrom django.views.decorators.csrf Import csrf_exemptfrom django.contrib.sessions.models Import  Sessionfrom django.contrib.auth.decorators Import login_required import Redis @login_requireddef Home (Request): Comments = Comments.objects.select_related (). All () [0:100] return render (Request, ' index.html ', Locals ()) @csrf_ Exemptdef Node_api (Request): Try: #通过sessionid获得 user session = Session.objects.get (session_key=request.     Post.get (' SessionID ')) user_id = session.get_decoded (). Get (' _auth_user_id ') user = User.objects.get (id=user_id) #创建Comment 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)) 

Let's see what's going on here. Home is a standard view file. Use select_related to get each comment username instead of returning a comment query collection the first time the page is loaded.

The second one is the view that our node app sends messages to. We get the SessionID from post, and then we get the UserID by decoding it. Once you have determined that the user exists, you can create the comment. Now, username and comment are sent to Redis server. Finally, send the data to the channel called "Chat" here.

URLs

It's easier here because we're going to use Django's own views and template.

From Django.conf.urls import patterns, include, url urlpatterns = Patterns ("',  url (r ' ^$ ', ' core.views.home ', name= ' Home '),  url (r ' ^node_api$ ', ' Core.views.node_api ', name= ' Node_api '),  url (r ' ^login/$ ', ' Django.contrib.auth.views.login ', {' template_name ': ' admin/login.html '}, name= ' login '),  url (r ' ^logout/$ ', ' Django.contrib.auth.views.logout ', {' next_page ': '/'}, Name= ' logout '),)

Start It up!

Open servers.

Python manage.py runserver localhost:3000 #In A new Terminal tab CD into the Nodejs directory we created Earliernode chat. Js

I put the code on GitHub. If you want to do it better, allow the user to create and join the chat room. You can also use PHP or rails to develop.

If you have any questions, please write or contact me at the comment office.

  • Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.