Django中如何使用Channels功能
目录
- 一、什么是WebSocket
- 二、什么是Channels
- 三、Django中使用Channel
- 四、前端Websocket使用
- 五、测试Channels功能
一、什么是WebSocket WebSocket是一种在单个TCP连接上进行全双工通讯的协议。WebSocket允许服务端主动向客户端推送数据。
在WebSocket协议中,客户端浏览器和服务器只需要完成一次握手就可以创建持久性的连接,并在浏览器和服务器之间进行双向的数据传输。
WebSocket的响应头中重要的字段:
HTTP/1.1 101 Swi tching Protocols:切换协议,WebSocket协议通过HTTP协议来建立运输层的TCP连接
Connection和Upgrade:表示服务端发起的WebSocket响应
Sec-WebSocket-Accept:表示服务器接受了客户端的请求,由Sec-WebSocket-Key计算得来
WebSocket协议的优点:
支持双向通信,实时性更强
数据格式比较轻量,性能开销小,通信高效
支持扩展,用户可以扩展协议或者实现自定义的子协议(比如支持自定义压缩算法等)
WebSocket协议的缺点:
少部分浏览器不支持,浏览器支持的程度与方式有区别
长连接对后端处理业务的代码稳定性要求更高,后端推送功能相对复杂
成熟的HTTP生态下有大量的组件可以复用,WebSocket较少
WebSocket的应用场景:
即时聊天通信,网站消息通知
在线协同编辑,如腾讯文档
多玩家在线游戏,视频弹幕,股票基金实施报价
二、什么是Channels Django本身不支持WebSocket,但可以通过集成Channels框架来实现WebSocket
Channels是针对Django项目的一个增强框架,可以使Django不仅支持HTTP协议,还能支持WebSocket,MQTT等多种协议,同时Channels还整合了Django的auth以及session系统方便进行用户管理及认证。
2.1channels文件和配置的含义
asgi.py:介于网络协议服务和Python应用之间的接口,能够处理多种通用协议类型,包括HTTP、HTTP2和WebSocket
channel_layers:在settings.py中配置。类似于一个通道,发送者(producer)在一段发送消息,消费者(consumer)在另一端进行监听
routings.py:相当于Django中的urls.py
consumers.py:相当于Django中的views.py
2.2channels文档链接
https://channels.readthedocs.io/en/latest/introduction.html
2.3.WSGI和ASGI不同
WSGI(Python Web Server Gateway Interface):为Python语言定义的Web服务器和Web应用程序或者框架之间的一种简单而通用的接口。
ASGI(Asynchronous Web Server Gateway Interface):异步网关协议接口,一个介于网络协议服务和Python应用之间的标准接口,能够处理多种通用的协议类型,包括HTTP,HTTP2和WebSocket。
三、Django中使用Channel 3.1安装channels
pip install channels==2.1.73.2修改setting.py文件
INSTALLED_APPS = ['django.contrib.staticfiles',... ...'channels',] # 指定ASGI的路由地址ASGI_APPLICATION = 'webapp.routing.application' #ASGI_APPLICATION 指定主路由的位置为webapp下的routing.py文件中的application
3.3setting.py的同级目录下创建routing.py路由文件,routing.py类似于Django中的url.py指明websocket协议的路由
from channels.auth import AuthMiddlewareStackfrom channels.routing import ProtocolTypeRouter, URLRouterfrom channels.security.websocket import AllowedHostsOriginValidatorimport webapp.routing application = ProtocolTypeRouter({'websocket':AllowedHostsOriginValidator(AuthMiddlewareStack(URLRouter(webapp.routing.websocket_urlpatterns)))})
ProtocolTypeRouter:ASGI支持多种不同的协议,在这里可以指定特定协议的路由信息,这里只使用了websocket协议,这里只配置websocket即可
AllowedHostsOriginValidator:指定允许访问的IP,设置后会去Django中的settings.py中去查找ALLOWED_HOSTS设置的IP
AuthMiddlewareStack:用于WebSocket认证,继承了Cookie Middleware,SessionMiddleware,SessionMiddleware。
django的channels封装了django的auth模块,使用这个配置我们就可以在consumer中通过下边的代码获取到用户的信息,和请求的url路径
self.sc
def connect(self):self.user = self.scope["user"]self.request_url = self.scope['path']
ope类似于django中的request,包含了请求的type、path、header、cookie、session、user等等有用的信息
URLRouter: 指定路由文件的路径,也可以直接将路由信息写在这里,代码中配置了路由文件的路径,会去对应应用下的routeing.py文件中查找websocket_urlpatterns
【Django中如何使用Channels功能】3.4webapp.routing.py内容如下
from django.urls import pathfrom webapp.consumers import ChatConsumer websocket_urlpatterns = [path('ws/chat/',ChatConsumer)]
routing.py路由文件跟django的url.py功能类似,语法也一样,意思就是访问ws/chat/都交给ChatConsumer处理。
3.5在要使用WebSocket的应用中创建consumers.py,consumers.py是用来开发ASGI接口规范的python应用,而Django中的view.py是用来开发符合WSGI接口规范的python应用。
from channels.generic.websocket import WebsocketConsumerfrom channels.generic.websocket import AsyncWebsocketConsumerimport json,time
Channels支持同步,也支持异步方式
同步方式代码如下:
class ChatConsumer(WebsocketConsumer):# websocket建立连接时执行方法def connect(self):self.accept()# websocket断开时执行方法def disconnect(self, close_code):self.close()# 从websocket接收到消息时执行函数def receive(self, text_data):text_data_json = json.loads(text_data)message = f'结果:{text_data_json}'self.send(text_data=https://www.it610.com/article/json.dumps({'message': message}))
异步方式代码如下:
class ChatConsumer(AsyncWebsocketConsumer):#websocket建立连接时执行方法async def connect(self):await self.accept() # websocket断开时执行方法async def disconnect(self, close_code):print(close_code) # 从websocket接收到消息时执行函数async def receive(self, text_data):for i in range(10):time.sleep(i)message = '结果: ' + str(i)await self.send(text_data=https://www.it610.com/article/json.dumps({'message': message}))
需要注意的是在异步中所有的逻辑都应该是异步的,不可以那同步的和异步的代码混合使用。
四、前端Websocket使用 WebSocket对象一个支持四个消息:onopen,onmessage,oncluse和onerror
onopen: 当浏览器和websocket服务端连接成功后会触发onopen消息
onerror: 如果连接失败,或者发送、接收数据失败,或者数据处理出错都会触发onerror消息
onmessage: 当浏览器接收到websocket服务器发送过来的数据时,就会触发onmessage消息,参数e包含了服务端发送过来的数据
onclose: 当浏览器接收到websocket服务器发送过来的关闭连接请求时,会触发onclose消息
拼接websocket请求地址,建立长连接
var chatSocket = new WebSocket('ws://' + window.location.host + '/ws/ver_update/');
连接事件
chatSocket.onopen = function () {console.log(getCurrentDate(2) + ' ' + 'websocket connection success')};
错误事件
chatSocket.onerror = function () {console.error(getCurrentDate(2) + ' ' + 'websocket connection error')};
关闭事件
chatSocket.onclose = function (e) {layer.msg('websocket关闭,检查错误日志', {icon: 2}); console.error(getCurrentDate(2) + ' ' + 'websocket closed unexpectedly 状态码:' + e.code); chatSocket.close(); };
接收事件
chatSocket.onmessage = function (e) {var data = https://www.it610.com/article/JSON.parse(e.data); }
五、测试Channels功能
文章图片
总结:自从使用Websocket功能后,再也没发生前端突然断开的情况了,对于长时间运行的任务,使用websocket是不错的选择~,有不足的地方请多多指教
到此这篇关于Django中使用Channels功能的文章就介绍到这了,更多相关Django使用Channels内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
推荐阅读
- 热闹中的孤独
- Shell-Bash变量与运算符
- JS中的各种宽高度定义及其应用
- 2021-02-17|2021-02-17 小儿按摩膻中穴-舒缓咳嗽
- 深入理解Go之generate
- 考研英语阅读终极解决方案——阅读理解如何巧拿高分
- 异地恋中,逐渐适应一个人到底意味着什么()
- 如何寻找情感问答App的分析切入点
- 我眼中的佛系经纪人
- 《魔法科高中的劣等生》第26卷(Invasion篇)发售