【全栈开发】---- 一文掌握 Websocket 原理,并用 Django 框架实现

devtools/2025/3/11 1:14:44/

目录

介绍

底层原理

握手环节详解:

收发数据(加密)

Django 中配置 channels

1、注册 channels

2、在 settings.py 中添加 asgi_application

3、修改 asgi.py 文件

4、routing 

5、consumers

实现 聊天室


介绍

        WebSocket是一种先进的通信协议,旨在通过单个长时间运行的连接实现实时双向数据交换,极大地提升了Web应用程序的交互性和响应速度。不同于传统的HTTP请求-响应模型,WebSocket在客户端与服务器之间开启了一个持久化的连接,使得双方可以随时发送文本或二进制数据,无需为每次通信重新建立连接,从而减少了延迟并提高了效率。这种特性特别适用于需要实时更新的应用场景,如在线游戏、即时通讯、金融交易监控等。WebSocket协议不仅简化了开发流程,还确保了更高效的数据传输,支持更高的并发量和更低的资源消耗,成为现代Web开发中不可或缺的技术之一。此外,随着互联网技术的发展,WebSocket正逐渐成为构建高度互动和动态Web应用的标准选择,为企业提供前所未有的用户体验改进机会。

底层原理

http 协议:

。连接

。数据传输(请求和响应)

。断开连接

websocket 协议:

。连接,客户端发起

。握手(验证),客户端发送一个消息,服务端接收到消息后做一些特殊处理并返回。服务端支持 websocket 协议

。收发数据(加密)

。断开连接

握手环节详解:

创建完链接后,客户端会自己生成一串随机字符串,并且加密后以密文的形式存储到客户端,以明文发送给服务端,服务端加密后发送给客户端,客户端比较自己加密算法得到的密文与服务端发送过来的密文是否相同,若相同,则服务端支持 websocket 协议,即握手成功,可以进行下一步操作,否则则不支持。

客户端发送给服务端的是这玩意:

GET /chatsocket HTTP/1.1

Host: 127.0.0.1:8002

Connection: Upgrade

Pragma: no-cache

Cache-Control: no-cache

Upgrade: websocket

Origin: http://localhost:63342

Sec-WebSocket-Version: 13

Sec-WebSocket-Key: mnwFxiOlctXFN/DeMt1Amg==

Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits

...

...

\r\n\r\n

服务端真正接收的是 Sec-WebSocket-Key

mnwFxiOlctXFN/DeMt1Amg==

然后将服务端将 Sec-WebSocket-Key 与 magic_string 进行字符串拼接

magic_string 有个固定值:258EAFA5-E914-47DA-95CA-C5AB0DC85B11

再将拼接的字符串进行 hmac1 加密,再进行 base64 加密

服务端将最后加密得到的结果返还给客户端,返还新式如下:

"HTTP/1.1 101 Switching Protocols\r\n" \

"Upgrade:websocket\r\n" \

"Connection: Upgrade\r\n" \

"Sec-WebSocket-Accept: 最终密文

然后客户端将服务端发送的密文和客户端自己产生的密文进行比较,相同则牵手成功。

收发数据(加密)

收发数据加密我看不懂,也不想去懂,大家可以自己搜搜视频看看。

Django 中配置 channels

django 默认不支持 websocket ,需要安装组件:

pip install channels

配置

1、注册 channels

INSTALLED_APPS = ["django.contrib.admin","django.contrib.auth","django.contrib.contenttypes","django.contrib.sessions","django.contrib.messages","django.contrib.staticfiles","app01.apps.App01Config","channels",
]

2、在 settings.py 中添加 asgi_application

ASGI_APPLICATTON = "lang_poll.asgi.application"

这里的 lang_poll 是自己的 Django 项目名称

3、修改 asgi.py 文件

原来的 asgi.py 文件只能处理 http 请求,现在加入 websocket 后需要修改:

"""
ASGI config for lang_poll project.It exposes the ASGI callable as a module-level variable named ``application``.For more information on this file, see
https://docs.djangoproject.com/en/5.1/howto/deployment/asgi/
"""import os
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter,URLRouter
from . import  routingos.environ.setdefault("DJANGO_SETTINGS_MODULE", "lang_poll.settings")
# application = get_asgi_application()application = ProtocolTypeRouter({"http": get_asgi_application(),"websocket": URLRouter(routing.websocket_urlpatterns),
})

4、routing 

asgi.py 中的 routing 是自己编写的文件,相当于 http 中的 urls.py,创建在 asgi.py 相同目录中:

from django.urls import re_path
from app01 import consumerswebsocket_urlpatterns = [re_path(r'ws/(?P<group>\w+)/$', consumers.ChatConsumer.as_asgi()),
]

5、consumers

这里的 consumers 也得自己创建,放在 app01 目录下,相当于 views.py ,用来编写 websocket 请求的响应逻辑:

from channels.generic.websocket import WebsocketConsumer
from channels.exceptions import StopConsumerclass ChatConsumer(WebsocketConsumer):def websocket_connect(self,message):# 客户端发送 websocket请求时,会自动触发这个函数# accept 函数允许客户端与服务端建立联系self.accept()def websocket_receive(self,message):# 客户端向服务端基于 websocket发送数据时,会自动触发该函数,并接收消息self.send("不要回复")# self.close()  是服务端主动断开连接def websocket_disconnect(self,message):# 客户端与服务端断开连接时,自动触发print("断开连接")raise StopConsumer()

实现 聊天室

前端页面可就用之前轮询的:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><style>.message{width: 200px;height: 300px;border: 1px solid orangered;}</style>
</head>
<body>
<div class="message" id="message"></div>
<div class="input"><input type="text" placeholder="请输入" id="txt"><input type="button" value="发送">
</div>
</body>
</html>

因为博主最近事比较多,聊天功能就不实现了,请见谅,后期会补回来的。


http://www.ppmy.cn/devtools/166155.html

相关文章

《Windows命令提示符(CMD)函数全解析与应用研究》

## 摘要 本文深入探讨了Windows命令提示符&#xff08;CMD&#xff09;的核心功能和应用。文章详细解析了CMD的基本命令、批处理脚本编写技巧以及高级功能&#xff0c;包括网络命令、系统管理命令和磁盘管理命令。通过实际案例研究&#xff0c;展示了CMD在系统管理、网络配置和…

专升本业务管理系统(源码+文档+讲解+演示)

引言 在教育领域&#xff0c;特别是高等教育阶段&#xff0c;专升本业务管理系统为学生、教师和管理人员提供了一个全面、高效的数字化管理平台。该系统旨在简化和优化专升本流程&#xff0c;提高教育管理的效率和透明度。本文将详细介绍专升本业务管理系统的功能、技术架构以…

开源模型应用落地-安全合规篇-用户输入价值观判断(四)

一、前言 在深度合规功能中,对用户输入内容的价值观判断具有重要意义。这一功能不仅仅是对信息合法性和合规性的简单审核,更是对信息背后隐含的伦理道德和社会责任的深刻洞察。通过对价值观的判断,系统能够识别可能引发不当影响或冲突的内容,从而为用户提供更安全、更和谐的…

【Linux】缓冲区

目录 一、什么是缓冲区 二、为什么要引入缓冲区机制 三、缓冲类型 四、FILE 简单设计一下libc库 一、什么是缓冲区 缓冲区是内存空间的一部分。也就是说&#xff0c;在内存空间中预留了一定的存储空间&#xff0c;这些存储空间用来缓冲输入或输出的数据&#xff0c;这部分…

【新人系列】Golang 入门(三):条件循环

✍ 个人博客&#xff1a;https://blog.csdn.net/Newin2020?typeblog &#x1f4dd; 专栏地址&#xff1a;https://blog.csdn.net/newin2020/category_12898955.html &#x1f4e3; 专栏定位&#xff1a;为 0 基础刚入门 Golang 的小伙伴提供详细的讲解&#xff0c;也欢迎大佬们…

【基础5】归并排序

核心思路 归并排序基本思想是将一个数组分成两个子数组&#xff0c;分别对这两个子数组进行排序&#xff0c;然后将排好序的子数组合并成一个最终的有序数组&#xff0c;即分治法&#xff1a; ​分​&#xff1a;将数组递归拆分成左右两半&#xff0c;直到每个子数组只剩1个元…

Python实例:PyMuPDF实现PDF翻译,英文翻译为中文,并按段落创建中文PDF

基于PyMuPDF与百度翻译的PDF翻译处理系统开发:中文乱码解决方案与自动化排版实践 一 、功能预览:将英文翻译为中文后创建的PDF 二、完整代码 from reportlab.lib.pagesizes import letter from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle

如何利用Python爬虫按图搜索1688商品(拍立淘):实战指南

在电商领域&#xff0c;按图搜索商品&#xff08;类似“拍立淘”功能&#xff09;是一种非常实用的功能&#xff0c;尤其适合用户通过图片快速查找相似商品。1688开放平台提供了按图搜索商品的API接口&#xff0c;允许开发者通过图片获取相关的商品信息。本文将详细介绍如何使用…