欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用Node.js和Socket.IO擴展Django的實時處理功能

 更新時間:2015年04月20日 11:42:28   投稿:goldensun  
這篇文章主要介紹了使用Node.js和Socket.IO擴展Django的實時處理功能,用異步處理實時功能是相當強大的,文中給出的例子是建立一個實時聊天室,需要的朋友可以參考下

 今天,我們的目標是使用Django,Redis,和Socket.IO建立一個實時的聊天室。雖然幾乎所有的Web應用程序都可以建立一個聊天室的。這篇文章將以較高的水平告訴你如何將基于REST的應用程序轉(zhuǎn)換成一個實時的Web應用程序的。我會使用Django創(chuàng)建REST的部分,實際上自由地使用任何你舒服的語言/框架均可。接下來,讓我們跳進代碼,先列舉我們所需要的部分。

組成:

  •     Django 1.4+
  •     Redis 2.6.x (版本可選,但是建議使用)
  •     Redis-py 2.7.x (僅當你使用Redis時需要)
  •     Node.js v0.8.x
  •     Socket.IO v0.9.x
  •     Cookie v0.0.5
  •     數(shù)據(jù)庫、sqlite、其他你覺得類似數(shù)據(jù)庫形式的 均可


 

你的使用的版本可能與我不同,我暫時未測試其他版本,全部使用當前最新穩(wěn)定版本。如果你無法通過下面方法安裝,我已經(jīng)編譯好Ubuntu的軟件包。你可以從評論中得到其他操作系統(tǒng)版本情況。
 

#https://docs.djangoproject.com/en/dev/topics/install/
sudo apt-get install python-pip
sudo pip install django
 
#http://redis.io/download
sudo apt-get install redis-server
 
#https://github.com/andymccurdy/redis-py
sudo pip install redis  
   
#https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager
sudo apt-get install python-software-properties
sudo add-apt-repository ppa:chris-lea/node.js
sudo apt-get update
sudo apt-get install nodejs
 
#https://github.com/LearnBoost/socket.io
npm install socket.io
 
#https://github.com/shtylman/node-cookie
npm install cookie

讓我們從Django Project開始
 

django-admin.py startproject realtime_tutorial && cd realtime_tutorial
python manage.py startapp core
mkdir nodejs

執(zhí)行完以上的代碼,django project就配置好了,接下來要做的是在settings文件中設置數(shù)據(jù)庫。先創(chuàng)建一個空白數(shù)據(jù)庫。(這是一個settings file的例子。在我的app中添加了一個“core”然后配置templates和urls的路徑。你可以隨意更改settings中的配置信息,但是要與你的app相對應。

Model

models很簡單,我們將要建一個包含user和text的表。如果你想讓他更復雜一些,可以添加chatroom等信息。(為了簡單起見,這里只寫了兩個)
 

from django.db import models
from django.contrib.auth.models import User
 
class Comments(models.Model):
  user = models.ForeignKey(User)
  text = models.CharField(max_length=255)

這就是我們將要使用的model,接下來執(zhí)行下面的syncdb代碼(第一行代碼),創(chuàng)建數(shù)據(jù)庫。然后創(chuàng)建幾個user來測試。(第二行代碼)

python manage.py syncdb
python manage.py createsuperuser
 
Node Server With Socket.IO

這一部分將要介紹實時信息的發(fā)送和獲取。使用Node.js創(chuàng)建一個依賴Socket.IO的app server,使用Redis 來做這項苦差事。在nodejs字典中,創(chuàng)建一個叫做“chat.js”的文件,然后把它放在這里:
 

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();

 
//訂閱chat channel


sub.subscribe('chat');

 
//配置socket.io來存儲Django設置的cookie
io.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) {
   
  //把信息從Redis發(fā)送到客戶端
  sub.on('message', function(channel, message){
    socket.send(message);
  });
   
  //客戶端通過socket.io發(fā)送消息
  socket.on('send_message', function (message) {
    values = querystring.stringify({
      comment: message,
      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
      }
    };
     
    //使用Django server發(fā)消息
    var req = http.get(options, function(res){
      res.setEncoding('utf8');
       
      //輸出錯誤信息
      res.on('data', function(message){
        if(message != 'Everything worked :)'){
          console.log('Message: ' + message);
        }
      });
    });
     
    req.write(values);
    req.end();
  });
});

首先,我們導入并創(chuàng)建http server來監(jiān)聽localhost 4000端口。然后訂閱Redis的 "chat" chanel。最后,只要我們在Django view中調(diào)用就可以了。


上次我們設置了Socket.IO能在本地領域使用cookie的那個Django設置,這能讓我們通過socket.handshake.cookie去訪問cookie數(shù)據(jù)。能讓我們怎樣得到用戶的session會話。

我們設置Socket.IO的cookies之后我們才能持有很多事件,第一個事件是Redis 發(fā)布通道,當我們的用戶注意到一個新的消息已經(jīng)被通知它將發(fā)送消息給所有站點的客戶端。

另一個事件是當客戶端通過Socket.IO發(fā)送一個信息,我們使用字符串查詢(queryString)模塊去創(chuàng)建一個query查詢才能被發(fā)送到我們的Django服務。我們的Django服務在本地端口3000將會運行但你能改變了那個需求。路徑設置成/node_api那個URL我們將不久創(chuàng)建在Django旁邊。一旦我們發(fā)送queryString我們等待的Django就會保存相關組件并給我們返回"Everything worked(都在工作)"。如果我們沒有得到返回給我們的輸出錯誤就關閉節(jié)點控制臺


一個關于不使用Redis的節(jié)點

你真的完全沒必要為這項目使用Redis,我發(fā)現(xiàn)它將是一個好的學習體驗,如果你想分流Redis你可以創(chuàng)建一個通道,使用表達式或一些其它類庫,在這上面的代碼會從Django里接收一個消息當一個注釋被保存時,然后你能通過Socket.IO添加注釋給所有的客戶端
模板

這就是我們所有HTML和javascript被放置的地方,它允許我們顯示注釋和交互我們的Node服務
 

<!DOCTYPE html>
<html>
<head>
 <title>Realtime Django</title>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js" type="text/javascript"></script>
 <script src="http://localhost:4000/socket.io/socket.io.js"></script>
 <script>
  $(document).ready(function(){
   var socket = io.connect('localhost', {port: 4000});
    
   socket.on('connect', function(){
    console.log("connect");
   });
    
   var entry_el = $('#comment');
        
   socket.on('message', function(message) {
    //Escape HTML characters
    var data = message.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
     
    //Append message to the bottom of the list
    $('#comments').append('<li>' + data + '</li>');
    window.scrollBy(0, 10000000000);
    entry_el.focus();
   });
           
   entry_el.keypress(function(event){
    //When enter is pressed send input value to node server
    if(event.keyCode != 13) return;
    var msg = entry_el.attr('value');
    if(msg){
      socket.emit('send_message', msg, function(data){
        console.log(data);
      });
     
    //Clear input value 
    entry_el.attr('value', '');
    }
   });
  });
 </script>
</head>
<body>
  <ul id="comments">
    {% for comment in comments %}
      <li>{{comment.user}}: {{comment.text}}</li>
    {% endfor %}
  </ul>
  <input type="text" id="comment" name="comment" />
</body>
</html>


在上面我們用socket.IO在本地端口4000連接我們的節(jié)點服務。當從服務器得到了一個信息我們就在目錄和添加它到我們注釋列表里做了些轉(zhuǎn)義,當我們想要發(fā)送一個信息我們就對輸入盒子里做了相應的13(按下一個鍵)的按鍵檢查。一旦那被按下后我們就發(fā)出信息給服務器使其被持有。一旦它被Django保存到我們的數(shù)據(jù)庫我們就得到一個"message"事件將其添加到我們的會話列表里

我們的Django顯示我們在下一步將加載一個"comments"變量,因此我們那樣設置并遍歷下面所有的循環(huán)。這部分僅僅是當頁面初始加載時使用了,我們的javascript將添加數(shù)據(jù)給這個目錄作為一個新的數(shù)據(jù)來自我們的Node服務

View

打開realtime_tutorial/core/views.py,然后像我一樣編輯:
 

from core.models import Comments, User
 
from django.shortcuts import render
from django.http import HttpResponse, HttpResponseServerError
from django.views.decorators.csrf import csrf_exempt
from django.contrib.sessions.models import Session
from django.contrib.auth.decorators import login_required
 
import redis
 
@login_required
def home(request):
  comments = Comments.objects.select_related().all()[0:100]
  return render(request, 'index.html', locals())
 
@csrf_exempt
def 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)
 
    #創(chuàng)建Comment
    Comments.objects.create(user=user, text=request.POST.get('comment'))
     
    #創(chuàng)建后就把它發(fā)送到聊天室
    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))

讓我們看看這里發(fā)生了什么。home是一個標準的view文件。使用select_related來獲得每一個comment的username,而不是在頁面第一次加載的時候,就返回一個comment的query集合。

第二個就是我們Node app發(fā)送信息的view。我們從POST中獲取sessionid,然后通過解碼獲得userid。確定user存在后,就可以創(chuàng)建comment了?,F(xiàn)在吧username 和 comment 發(fā)送到 Redis server。最后,把數(shù)據(jù)發(fā)送到這里叫做"chat"的頻道。

URLs

這里比較簡單,因為我們將要使用Django自帶的views和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!

打開servers。
 

python manage.py runserver localhost:3000
 
#In a new terminal tab cd into the nodejs directory we created earlier
node chat.js

我把代碼放到github。如果你想把它做得更好,就允許user創(chuàng)建、加入聊天室。你也可以使用PHP或者Rails開發(fā)。

如果你有什么問題,請在評論處寫下或聯(lián)系我。

相關文章

  • python如何生成密碼字典

    python如何生成密碼字典

    這篇文章主要介紹了python如何生成密碼字典,密碼字典主要是配合解密使用,下面利用python實現(xiàn)生成密碼字典,需要的小伙伴可以參考一下
    2022-03-03
  • python實現(xiàn)zencart產(chǎn)品數(shù)據(jù)導入到magento(python導入數(shù)據(jù))

    python實現(xiàn)zencart產(chǎn)品數(shù)據(jù)導入到magento(python導入數(shù)據(jù))

    這篇文章主要介紹了python實現(xiàn)zencart產(chǎn)品數(shù)據(jù)導入到magento(python導入數(shù)據(jù)),需要的朋友可以參考下
    2014-04-04
  • pycharm配置python環(huán)境的詳細圖文教程

    pycharm配置python環(huán)境的詳細圖文教程

    PyCharm是一款功能強大的Python編輯器,具有跨平臺性,下面這篇文章主要給大家介紹了關于pycharm配置python環(huán)境的詳細圖文教程,文中通過圖文介紹的非常詳細,需要的朋友可以參考下
    2023-01-01
  • Python中的time模塊與datetime模塊用法總結(jié)

    Python中的time模塊與datetime模塊用法總結(jié)

    Python中內(nèi)置的各項時間日期函數(shù)幾乎都來自于time和datetime這兩個模塊,下面整理了Python中的time模塊與datetime模塊用法總結(jié),需要的朋友可以參考下
    2016-06-06
  • python3?cookbook解壓可迭代對象賦值給多個變量的問題及解決方案

    python3?cookbook解壓可迭代對象賦值給多個變量的問題及解決方案

    這篇文章主要介紹了python3?cookbook-解壓可迭代對象賦值給多個變量,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2024-01-01
  • 用python實現(xiàn)彈球小游戲

    用python實現(xiàn)彈球小游戲

    大家好,本篇文章主要講的是用python實現(xiàn)彈球小游戲,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01
  • python中文編碼與json中文輸出問題詳解

    python中文編碼與json中文輸出問題詳解

    Python的編碼問題還是很讓人頭疼的,做下筆記幫助別人,也幫助自己,下面這篇文章主要給大家介紹了關于python中文編碼與json中文輸出問題的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2018-08-08
  • pandas groupby()的使用小結(jié)

    pandas groupby()的使用小結(jié)

    在數(shù)據(jù)分析中,經(jīng)常會用到分組,可用函數(shù)pandas中的groupby(),本文就來介紹一下pandas groupby()的使用小結(jié),具有一定的參考價值,感興趣的可以了解一下
    2023-11-11
  • Python使用BeautifulSoup爬取網(wǎng)頁數(shù)據(jù)的操作步驟

    Python使用BeautifulSoup爬取網(wǎng)頁數(shù)據(jù)的操作步驟

    在網(wǎng)絡時代,數(shù)據(jù)是最寶貴的資源之一,而爬蟲技術就是一種獲取數(shù)據(jù)的重要手段,Python 作為一門高效、易學、易用的編程語言,自然成為了爬蟲技術的首選語言之一,本文將介紹如何使用 BeautifulSoup 爬取網(wǎng)頁數(shù)據(jù),并提供詳細的代碼和注釋,幫助讀者快速上手
    2023-11-11
  • pandas中read_sql使用參數(shù)進行數(shù)據(jù)查詢的實現(xiàn)

    pandas中read_sql使用參數(shù)進行數(shù)據(jù)查詢的實現(xiàn)

    本文主要介紹了pandas中read_sql使用參數(shù)進行數(shù)據(jù)查詢的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-06-06

最新評論