WebSocket – 开启通往新世界的大门
WebSocket是什么?
WebSocket是一种在单个TCP连接上进行全双工通讯的协议。WebSocket允许服务端主动向客户端推送数据。在WebSocket协议中,客户端浏览器和服务器只本文来源gaodai#ma#com搞*!代#%^码网5需要完成一次握手就可以创建持久性的连接,并在浏览器和服务器之间进行双向的数据传输。
WebSocket有什么用?
WebSocket区别于HTTP协议的一个最为显著的特点是,WebSocket协议可以由服务端主动发起消息,对于浏览器需要及时接收数据变化的场景非常适合,例如在Django中遇到一些耗时较长的任务我们通常会使用Celery来异步执行,那么浏览器如果想要获取这个任务的执行状态,在HTTP协议中只能通过轮训的方式由浏览器不断的发送请求给服务器来获取最新状态,这样发送很多无用的请求不仅浪费资源,还不够优雅,如果使用WebSokcet来实现就很完美了
WebSocket的另外一个应用场景就是下文要说的聊天室,一个用户(浏览器)发送的消息需要实时的让其他用户(浏览器)接收,这在HTTP协议下是很难实现的,但WebSocket基于长连接加上可以主动给浏览器发消息的特性处理起来就游刃有余了
初步了解WebSocket之后,我们看看如何在Django中实现WebSocket
Channels
Django本身不支持WebSocket,但可以通过集成Channels框架来实现WebSocket
Channels是针对Django项目的一个增强框架,可以使Django不仅支持HTTP协议,还能支持WebSocket,MQTT等多种协议,同时Channels还整合了Django的auth以及session系统方便进行用户管理及认证。
我下文所有的代码实现使用以下python和Django版本
python==3.6.3 django==2.2
集成Channels
我假设你已经新建了一个django项目,项目名字就叫webapp,目录结构如下
project - webapp - __init__.py - settings.py - urls.py - wsgi.py - manage.py
1. 安装channels
pip install channels==2.1.7
2. 修改settings.py文件,
# APPS中添加channels INSTALLED_APPS = [ 'django.contrib.staticfiles', 'channels', ] # 指定ASGI的路由地址 ASGI_APPLICATION = 'webapp.routing.application'
channels运行于ASGI协议上,ASGI的全名是Asynchronous Server Gateway Interface。它是区别于Django使用的WSGI协议 的一种异步服务网关接口协议,正是因为它才实现了websocket
ASGI_APPLICATION 指定主路由的位置为webapp下的routing.py文件中的application
3. setting.py的同级目录下创建routing.py路由文件,routing.py类似于Django中的url.py指明websocket协议的路由
from channels.routing import ProtocolTypeRouter application = ProtocolTypeRouter({ # 暂时为空,下文填充 })
4. 运行Django项目
C:\python36\python.exe D:/demo/tailf/manage.py runserver 0.0.0.0:80 Performing system checks... Watching for file changes with StatReloader System check identified no issues (0 silenced). April 12, 2019 - 17:44:52 Django version 2.2, using settings 'webapp.settings' Starting ASGI/Channels version 2.1.7 development server at http://0.0.0.0:80/ Quit the server with CTRL-BREAK.
仔细观察上边的输出会发现Django启动中的Starting development server已经变成了Starting ASGI/Channels version 2.1.7 development server,这表明项目已经由django使用的WSGI协议转换为了Channels使用的ASGI协议