今天,我们的目标是使用Django,Redis,和Socket.IO建立一个实时的聊天室。虽然几乎所有的Web应用程序都可以建立一个聊天室的。这篇文章将以较高的水平告诉你如何将基于REST的应用程序转换成一个实时的Web应用程序的。我会使用Django创建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
- 数据库、sqlite、其他你觉得类似数据库形式的 均可
你的使用的版本可能与我不同,我暂时未测试其他版本,全部使用当前最新稳定版本。如果你无法通过下面方法安装,我已经编译好Ubuntu的软件包。你可以从评论中得到其他操作系统版本情况。
#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
执行完以上的代码,django project就配置好了,接下来要做的是在settings文件中设置数据库。先创建一个空白数据库。(这是一个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,接下来执行下面的syncdb代码(第一行代码),创建数据库。然后创建几个user来测试。(第二行代码)
python manage.py syncdb python manage.py createsuperuser Node Server With Socket.IO
这一部分将要介绍实时信息的发送和获取。使用Node.js创建一个依赖Socket.IO的app server,使用Redis 来做这项苦差事。在nodejs字典中,创建一个叫做“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发送到客户端 sub.on('message', function(channel, message){ socket.send(message); }); //客户端通过socket.io发送消息 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发消息 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(); }); });
首先,我们导入并创建http server来监听localhost 4000端口。然后订阅Redis的 "chat" chanel。最后,只要我们在Django view中调用就可以了。
上次我们设置了Socket.IO能在本地领域使用cookie的那个Django设置,这能让我们通过socket.handshake.cookie去访问cookie数据。能让我们怎样得到用户的session会话。
我们设置Socket.IO的cookies之后我们才能持有很多事件,第一个事件是Redis 发布通道,当我们的用户注意到一个新的消息已经被通知它将发送消息给所有站点的客户端。
另一个事件是当客户端通过Socket.IO发送一个信息,我们使用字符串查询(queryString)模块去创建一个query查询才能被发送到我们的Django服务。我们的Django服务在本地端口3000将会运行但你能改变了那个需求。路径设置成/node_api那个URL我们将不久创建在Django旁边。一旦我们发送queryString我们等待的Django就会保存相关组件并给我们返回"Everything worked(都在工作)"。如果我们没有得到返回给我们的输出错误就关闭节点控制台
一个关于不使用Redis的节点
你真的完全没必要为这项目使用Redis,我发现它将是一个好的学习体验,如果你想分流Redis你可以创建一个通道,使用表达式或一些其它类库,在这上面的代码会从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="//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,"&").replace(/</g,"<").replace(/>/g,">"); //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连接我们的节点服务。当从服务器得到了一个信息我们就在目录和添加它到我们注释列表里做了些转义,当我们想要发送一个信息我们就对输入盒子里做了相应的13(按下一个键)的按键检查。一旦那被按下后我们就发出信息给服务器使其被持有。一旦它被Django保存到我们的数据库我们就得到一个"message"事件将其添加到我们的会话列表里
我们的Django显示我们在下一步将加载一个"comments"变量,因此我们那样设置并遍历下面所有的循环。这部分仅仅是当页面初始加载时使用了,我们的javascript将添加数据给这个目录作为一个新的数据来自我们的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) #创建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))
让我们看看这里发生了什么。home是一个标准的view文件。使用select_related来获得每一个comment的username,而不是在页面第一次加载的时候,就返回一个comment的query集合。
第二个就是我们Node app发送信息的view。我们从POST中获取sessionid,然后通过解码获得userid。确定user存在后,就可以创建comment了。现在吧username 和 comment 发送到 Redis server。最后,把数据发送到这里叫做"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创建、加入聊天室。你也可以使用PHP或者Rails开发。
如果你有什么问题,请在评论处写下或联系我。

Python은 데이터 과학, 웹 개발 및 자동화 작업에 적합한 반면 C는 시스템 프로그래밍, 게임 개발 및 임베디드 시스템에 적합합니다. Python은 단순성과 강력한 생태계로 유명하며 C는 고성능 및 기본 제어 기능으로 유명합니다.

2 시간 이내에 Python의 기본 프로그래밍 개념과 기술을 배울 수 있습니다. 1. 변수 및 데이터 유형을 배우기, 2. 마스터 제어 흐름 (조건부 명세서 및 루프), 3. 기능의 정의 및 사용을 이해하십시오. 4. 간단한 예제 및 코드 스 니펫을 통해 Python 프로그래밍을 신속하게 시작하십시오.

Python은 웹 개발, 데이터 과학, 기계 학습, 자동화 및 스크립팅 분야에서 널리 사용됩니다. 1) 웹 개발에서 Django 및 Flask 프레임 워크는 개발 프로세스를 단순화합니다. 2) 데이터 과학 및 기계 학습 분야에서 Numpy, Pandas, Scikit-Learn 및 Tensorflow 라이브러리는 강력한 지원을 제공합니다. 3) 자동화 및 스크립팅 측면에서 Python은 자동화 된 테스트 및 시스템 관리와 같은 작업에 적합합니다.

2 시간 이내에 파이썬의 기본 사항을 배울 수 있습니다. 1. 변수 및 데이터 유형을 배우십시오. 이를 통해 간단한 파이썬 프로그램 작성을 시작하는 데 도움이됩니다.

10 시간 이내에 컴퓨터 초보자 프로그래밍 기본 사항을 가르치는 방법은 무엇입니까? 컴퓨터 초보자에게 프로그래밍 지식을 가르치는 데 10 시간 밖에 걸리지 않는다면 무엇을 가르치기로 선택 하시겠습니까?

Fiddlerevery Where를 사용할 때 Man-in-the-Middle Reading에 Fiddlereverywhere를 사용할 때 감지되는 방법 ...

Python 3.6에 피클 파일로드 3.6 환경 보고서 오류 : modulenotfounderror : nomodulename ...

경치 좋은 스팟 댓글 분석에서 Jieba Word 세분화 문제를 해결하는 방법은 무엇입니까? 경치가 좋은 스팟 댓글 및 분석을 수행 할 때 종종 Jieba Word 세분화 도구를 사용하여 텍스트를 처리합니다 ...


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

Eclipse용 SAP NetWeaver 서버 어댑터
Eclipse를 SAP NetWeaver 애플리케이션 서버와 통합합니다.

PhpStorm 맥 버전
최신(2018.2.1) 전문 PHP 통합 개발 도구

안전한 시험 브라우저
안전한 시험 브라우저는 온라인 시험을 안전하게 치르기 위한 보안 브라우저 환경입니다. 이 소프트웨어는 모든 컴퓨터를 안전한 워크스테이션으로 바꿔줍니다. 이는 모든 유틸리티에 대한 액세스를 제어하고 학생들이 승인되지 않은 리소스를 사용하는 것을 방지합니다.

Dreamweaver Mac版
시각적 웹 개발 도구

MinGW - Windows용 미니멀리스트 GNU
이 프로젝트는 osdn.net/projects/mingw로 마이그레이션되는 중입니다. 계속해서 그곳에서 우리를 팔로우할 수 있습니다. MinGW: GCC(GNU Compiler Collection)의 기본 Windows 포트로, 기본 Windows 애플리케이션을 구축하기 위한 무료 배포 가능 가져오기 라이브러리 및 헤더 파일로 C99 기능을 지원하는 MSVC 런타임에 대한 확장이 포함되어 있습니다. 모든 MinGW 소프트웨어는 64비트 Windows 플랫폼에서 실행될 수 있습니다.
