首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

Node.js + Socket.IO 擴展 Django 即時功能:Redis 發布/訂閱實現即時聊天室

     編輯:更多程式設計知識

Django 同步阻塞模型難以支援高併發即時推播。引入 Node.js + Socket.IO 處理 WebSocket 連線,透過 Redis Pub/Sub 傳遞訊息,實現即時聊天室。架構:瀏覽器 ←WS→ Node.js ←Pub/Sub→ Redis ←Pub→ Django 視圖。

技術棧

  • Django 1.4+、Redis 2.6+、redis-py 2.7+
  • Node.js 0.8+、Socket.IO 0.9+、cookie 0.0.5

安裝指令


pip install django redis
sudo apt-get install redis-server
# Node.js
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
npm install socket.io cookie

Django 端:模型、視圖、路由


# models.py
class Comment(models.Model):
    user = models.ForeignKey(User)
    text = models.CharField(max_length=255)

# views.py
@login_required
def home(request):
    comments = Comment.objects.select_related().all()[:100]
    return render(request, 'index.html', {'comments': comments})

@csrf_exempt
def node_api(request):
    session = Session.objects.get(session_key=request.POST['sessionid'])
    user_id = session.get_decoded()['_auth_user_id']
    user = User.objects.get(id=user_id)
    Comment.objects.create(user=user, text=request.POST['comment'])
    r = redis.StrictRedis()
    r.publish('chat', '%s: %s' % (user.username, request.POST['comment']))
    return HttpResponse("Everything worked :)")

Node.js 端:Socket.IO 伺服器


// nodejs/chat.js
var http = require('http');
var server = http.createServer().listen(4000);
var io = require('socket.io').listen(server);
var cookie = require('cookie');
var querystring = require('querystring');
var redis = require('socket.io/node_modules/redis');
var sub = redis.createClient();
sub.subscribe('chat');

io.configure(function() {
    io.set('authorization', function(data, accept) {
        if (data.headers.cookie) {
            data.cookie = cookie.parse(data.headers.cookie);
            accept(null, true);
        } else accept('error', false);
    });
    io.set('log level', 1);
});

io.sockets.on('connection', function(socket) {
    sub.on('message', function(channel, msg) {
        socket.send(msg);
    });
    socket.on('send_message', function(msg) {
        var data = querystring.stringify({
            comment: msg,
            sessionid: socket.handshake.cookie['sessionid']
        });
        var opts = {
            host: 'localhost', port: 3000, path: '/node_api',
            method: 'POST',
            headers: {'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': data.length}
        };
        http.request(opts, function(res) {
            res.on('data', function(chunk) {
                if (chunk != 'Everything worked :)') console.log('Error:', chunk);
            });
        }).end(data);
    });
});

前端模板





    {% for c in comments %}
  • {{c.user}}: {{c.text}}
  • {% endfor %}

啟動方式


python manage.py runserver localhost:3000
node nodejs/chat.js

架構優勢

  • Django 專注業務邏輯與持久化,Node.js 專注長連線管理。
  • Redis 解耦雙方,可水平擴展多 Node.js 進程。
  • 現有 REST API 無需大改,僅新增 /node_api 端點。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved