ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

websocket在django中的运用

2026/9/21 1:32:51 拓冰建站 浏览量
websocket在django中的运用

14-2 聊天室实现思路:轮训、长轮训、websocket_哔哩哔哩_bilibili  参考大佬的B站学习笔记

https://www.cnblogs.com/wupeiqi/p/6558766.html    参考博客

https://www.cnblogs.com/wupeiqi/articles/9593858.html  参考博客


http: 是短连接,无状态的,一次性的,无法保证实时信息交互

  • 客户端主动连接服务器
  • 客户端向服务端发送消息,服务端接收到返回数据
  • 客户端接收到数据
  • 端口连接

websock协议创建持久的连接不断开,基于这个连接进行收发数据,建立在http上

  • 实时响应:接收发送消息
  • 实时图表,柱状图,饼图

websocket 原理:

  • 连接,客户端发起
  • 握手,客户端发送一个消息,后端接收到消息再做一些特殊处理返回(服务端要支持websocket协议)
  • 收发数据(加密)
  • 断开连接

握手流程:

        1.客户端向服务端发送

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

         2.服务端接收:

请求和响应的【握手】信息需要遵循规则:从请求【握手】信息中提取 Sec-WebSocket-Key利用magic_string 和 Sec-WebSocket-Key 进行hmac1加密,再进行base64加密将加密结果响应给客户端注:magic string固定为:258EAFA5-E914-47DA-95CA-C5AB0DC85B11

 返回数据给客户端浏览器,验证通过则完成握手

HTTP/1.1 101 Switching Protocols"Upgrade:websocket"Connection: Upgrade"Sec-WebSocket-Accept: 密文

 收发数据流程:

数据 b'asdfa;efawe;sdfas;awdfawea;sdfasdfaf;sdfasdfa;'

先获取第二个字节,8位  10001010

再获取第二个字节的后七位   0001010  -> payload len

  • =127  2个字节,8个字节      其他字节(4字节 masking key + 数据)
  • =126  2个字节,8个字节      其他字节(4字节 masking key + 数据)
  • <=125  2个字节                     其他字节(4字节 masking key + 数据)
  • 获取masking key,然后对数据进行解密
    • var DECODED = "";
      for (var i = 0; i < ENCODED.length; i++) {
          DECODED[i] = ENCODED[i] ^ MASK[i % 4];
      }

实时交互的解决方案:

  1. 轮训,浏览器每隔一段时间向后台发送一次请求。缺点:有延迟、请求太多网站压力大
  2. 长轮询,客户端向服务端发送请求,保持一定的时间,一旦有数据就立即返回。特点:数据无延迟,常应用于大平台、WebQQ、Web微信
  3. websocket,客户端和服务端创建连接不断开,可以实现双向通信。特点:旧版浏览器不支持

django 中配置websocket

pip install channels  # 安装组件# 注册app
'channels'  # 配置asgi.application
ASGI_APPLICATION = 'web.asgi.application'

更新asgi文件(在支持http的基础上支持websocket)

# asgi.pyimport os
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter,URLRouter
from . import routing
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'web.settings')application = ProtocolTypeRouter({'http':get_asgi_application(),'websocket':URLRouter(routing.websocket_urlpatterns),
})

创建routing文件在setting同级目录

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

创建app目录下consumer文件

from channels.generic.websocket import WebsocketConsumer
from channels.exceptions import StopConsumer"""
wsgi: 同步
asgi: 异步+asgi+websocket
"""
class ChatConsumer(WebsocketConsumer):def websocket_connect(self, message):# 客户端向后端发送websocket连接请求时自动触发# 容许和客户端创建连接self.accept()def websocket_receive(self, message):# 浏览器基于websocket向后端发送数据,自动触发接收消息print(message)self.send('不要回复!!!')def websocket_disconnect(self, message):# 客户端与服务端断开时自动触发raise StopConsumer

2024/02/26 更新中。。。