Django实现websocket完成实时通讯
一 什么是Websocket
WebSocket是一种在单个TCP连接上进行全双工通信的协议
WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输
现在,很多网站为了实现推送技术,所用的技术都是轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。
而比较新的技术去做轮询的效果是Comet。这种技术虽然可以双向通信,但依然需要反复发出请求。而且在Comet中,普遍采用的长链接,也会消耗服务器资源。
在这种情况下,HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯
二 Django实现Websocket
django实现websocket大致上有两种方式,一种channels,一种是dwebsocket。channels依赖于redis,twisted等,相比之下使用dwebsocket要更为方便一些
三 dwebsocket安装
pip3 install dwebsocket
四 dwebsocket配置
INSTALLED_APPS = [ ..... ..... 'dwebsocket', ]
setting.py 配置: WEBSOCKET_ACCEPT_ALL=True # 可以允许每一个单独的视图实用websockets
五 使用
项目结构:
1,路由层:
from django.conf.urls import url from . import views urlpatterns = [ url(r'^login/', views.login), url(r'^path/', views.path), ]
2,视图层:
# Create your views here. from django.shortcuts import render,HttpResponse from dwebsocket.decorators import accept_websocket def login(request): return render(request,'login.html') @accept_websocket def path(request): if request.is_websocket(): for message in request.websocket: if request.websocket.is_closed(): print('连接关闭') return HttpResponse('连接断开') else: print('--- request.is_websocket() 数据: --->>',message.decode()) request.websocket.send('django后台已下载完成'.encode('utf-8'))
3,html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="http://code.jquery.com/jquery-1.11.1.min.js"></script> </head> <body> <button onclick="WebSocketTest()">test</button> </body> <script type="text/javascript"> function WebSocketTest() { /*创建socket连接*/ if ("WebSocket" in window) { alert("您的浏览器支持 WebSocket!"); var socket = new WebSocket("ws://" + '127.0.0.1:8000' + "/path/"); socket.onopen = function () { console.log('WebSocket open');//成功连接上Websocket const sendData = { type: 'register', }; socket.send(JSON.stringify(sendData)); }; socket.onmessage = function (e) { alert('message: ' + e.data);//打印出服务端返回过来的数据 }; socket.onclose = function () { // 关闭 websocket alert("连接已关闭..."); }; } else { // 浏览器不支持 WebSocket alert("您的浏览器不支持 WebSocket!"); } } </script> </html>
六 详解
#dwebsocket有两种装饰器:require_websocket和accept_websocekt,使用require_websocket装饰器会导致视图函数无法接收导致正常的http请求,一般情况使用accept_websocket方式就可以了,
#
# dwebsocket的一些内置方法:
#
# request.is_websocket():判断请求是否是websocket方式,是返回true,否则返回false
# request.websocket: 当请求为websocket的时候,会在request中增加一个websocket属性,
# WebSocket.wait() 返回客户端发送的一条消息,没有收到消息则会导致阻塞
# WebSocket.read() 和wait一样可以接受返回的消息,只是这种是非阻塞的,没有消息返回None
# WebSocket.count_messages()返回消息的数量
# WebSocket.has_messages()返回是否有新的消息过来
# WebSocket.send(message)像客户端发送消息,message为byte类型
完整项目下载:
链接:https://pan.baidu.com/s/1ju0Qj4P2Gm7oI86RXqIh-A
提取码:0ny4
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现