Django+websocket实现一个简单聊天

news2024/11/24 5:41:09

WebSocket是一种在单个TCP连接上进行全双工通信的协议。它由IETF在2011年定为标准RFC 6455,并由RFC7936补充规范,同时WebSocket API也被W3C定为标准。

1、定义与原理

WebSocket是独立的、创建在TCP上的协议,它使用HTTP/1.1协议的101状态码进行握手。为了创建WebSocket连接,需要通过浏览器发出请求,之后服务器进行回应,这个过程通常称为“握手”(handshaking)。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输。

2、特点

  1. 双向通信:WebSocket支持客户端和服务器之间的实时双向通信,而传统的HTTP协议是单向请求-响应模式。
  2. 实时性强:由于协议是全双工的,服务器可以随时主动给客户端下发数据,相对于HTTP请求需要等待客户端发起请求服务端才能响应,WebSocket的延迟明显更少。
  3. 保持连接状态:WebSocket需要先创建连接,因此是一种有状态的协议,之后通信时可以省略部分状态信息。而HTTP请求可能需要在每个请求都携带状态信息(如身份认证等)。
  4. 控制开销小:在连接创建后,服务器和客户端之间交换数据时,用于协议控制的数据包头部相对较小。相对于HTTP请求每次都要携带完整的头部,WebSocket的开销显著减少了。
  5. 支持二进制:WebSocket定义了二进制帧,可以更轻松地处理二进制内容。
  6. 支持扩展:WebSocket定义了扩展,用户可以扩展协议、实现部分自定义的子协议,如部分浏览器支持压缩等。
  7. 更好的压缩效果:相对于HTTP压缩,WebSocket在适当的扩展支持下,可以沿用之前内容的上下文,在传递类似的数据时,可以显著地提高压缩率。

3.案列

(1)先创建一个django项目(cmd创建或者直接pychram点击创建)

        这里我们需要添加channels插件

         pip install channels==3.0

        在创建一个app用来访问页面,顺便创建需要用到的文件

(2)settings.py (配置一下环境)

        在apps里面注册一下

在添加以下配置

ASGI_APPLICATION = "websocket.asgi.application"//"websocket"是我的项目名


#channels自带的存储
CHANNEL_LAYERS = {
    "default":{
        "BACKEND": "channels.layers.InMemoryChannelLayer",
    }
}

运行检查一下,配置成功的话会有ASGI/Channels的标识(不对的话就切换成3.0的channels版本)

(3)项目目录下  asgi.py

   这里主要是用来区分是http协议还是websocket协议

import os

from channels.routing import ProtocolTypeRouter,URLRouter
from django.core.asgi import get_asgi_application
from websocket import routings

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'study_websocket.settings')

#application = get_asgi_application()
application = ProtocolTypeRouter({
    "http": get_asgi_application(),
    "websocket":URLRouter(routings.websocket_urlpatterns),
})

 (4) 项目目录routings.py

from django.urls import re_path
from app import consumers

websocket_urlpatterns = [
    re_path(r'room/(?P<group>\w+)/$',consumers.ChatConsumer.as_asgi()),
]

(5)创建一个路由来访问聊天页面

url.py

from django.contrib import admin
from django.urls import path
from app import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('',views.index),
]

views.py

from django.shortcuts import render

# Create your views here.


def index(request):
    num = request.GET.get('num')
    return render(request,"home.html",{"num":num})

tempaltes文件创建一个home.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .message {
            height: 500px;
            border: 1px solid #dddd;
            width: 100%;
        }
    </style>
</head>
<body>
<div class="message" id="message"></div>
<div>
    <input type="text" placeholder="请输入" id="txt">
    <input type="button" value="发送" onclick="sendMessage()">
    <input type="button" value="关闭" onclick="closeCount()">
</div>
</body>
<script>
    //创建连接
    socket = new WebSocket("ws://127.0.0.1:8000/room/{{ num }}/");

    //创建好连接之后自动触发(服务端执行self.accept())
    socket.onopen = function (event){
        let tag= document.createElement("div")
        tag.innerText = "[连接成功]";
        document.getElementById("message").appendChild(tag);
    }

    //当websocket接收到服务端发来的消息时,自动触发这个函数
    socket.onmessage = function (event){
        console.log(event.data)
        let tag= document.createElement("div")
        tag.innerText = event.data;
        document.getElementById("message").appendChild(tag);
    }

    function sendMessage(){
        let tag=document.getElementById("txt");
        socket.send(tag.value);
    }

    function closeCount(){
        socket.close()//关闭
    }
</script>
</html>

(6)consumers.py

from channels.generic.websocket import WebsocketConsumer
from channels.exceptions import StopConsumer
from asgiref.sync import async_to_sync


class ChatConsumer(WebsocketConsumer):
    def websocket_connect(self, message):
        #有客户端来向后台发送websocket连接请求时,自动触发
        #服务端允许客户端创建连接
        print("有人连接")
        self.accept()

        #获取群号
        group = self.scope['url_route']['kwargs'].get("group")
        #将这个客户端连接对象加入到内存
        #channel_layer.group_add这个方法默认是异步的所有需要async_to_sync转成同步
        async_to_sync(self.channel_layer.group_add)(group,self.channel_name)


     #浏览器基于websocket向后端发送数据,自动触发接收消息
    def websocket_receive(self, message):
        #获取群号
        group = self.scope['url_route']['kwargs'].get("group")
        #通知组内所有客户端,执行xx_oo方法,在此方法中可以自己定义任意功能
        async_to_sync(self.channel_layer.group_send)(group,{"type":"xx_oo","message":message})
    def xx_oo(self, event):
        text = event["message"]["text"]
        self.send(text)

    def websocket_disconnect(self, message):
        print("客户端断开连接")
        group = self.scope['url_route']['kwargs'].get("group")
        #客户端与服务器断开连接时自动触发
        async_to_sync(self.channel_layer.group_discard)(group,self.channel_name)
        raise StopConsumer()

效果:

同一个num名下才能收到消息

这里只实现了核心功能,具体的样式和效果可以各自发挥,适应各自的场景中。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2229871.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MATLAB实现人类学习优化算法HLO

1.算法简介 人类学习优化算法&#xff08;Human Learning-based Optimization&#xff0c;HLO&#xff09;是一种基于人类学习过程开发的启发式算法。HLO算法的设计灵感来源于人类的智慧和经验&#xff0c;特别是人类在学习和调整过程中展现出的适应性、学习能力和创新思维。该…

【果蔬识别】Python+卷积神经网络算法+深度学习+人工智能+机器学习+TensorFlow+计算机课设项目+算法模型

一、介绍 果蔬识别系统&#xff0c;本系统使用Python作为主要开发语言&#xff0c;通过收集了12种常见的水果和蔬菜&#xff08;‘土豆’, ‘圣女果’, ‘大白菜’, ‘大葱’, ‘梨’, ‘胡萝卜’, ‘芒果’, ‘苹果’, ‘西红柿’, ‘韭菜’, ‘香蕉’, ‘黄瓜’&#xff09;…

Android 策略设计模式的使用:使用设计模式,减少烂代码,让项目更好维护

目录 大家好呀~&#xff0c;我是前期后期&#xff0c;在网上冲浪的一名程序员&#xff0c;分享一些自己学到的知识&#xff0c;希望对大家有所帮助 前言&#xff1a;为什么要使用设计模式 在项目开发过程中&#xff0c;我们会对接很多种支付&#xff1a;国内&#xff08;微信…

uniapp和vite项目配置多环境编译,增加测试环境变量配置--mode test

如果你的项目是使用vite和uniapp配置开发的&#xff0c;就可以在代码里面获取到这些变量&#xff0c;但是开发&#xff0c;测试和发布是不同的请求地址&#xff0c;所以需要配置。Vite 使用 dotenv 从你的 环境目录 中的下列文件加载额外的环境变量&#xff1a; .env …

动态规划 - 编辑距离

115. 不同的子序列 困难 给你两个字符串 s 和 t &#xff0c;统计并返回在 s 的 子序列 中 t 出现的个数&#xff0c;结果需要对 10^9 7 取模。 算法思想&#xff1a;利用动态规划&#xff0c;分s[i - 1] 与 t[j - 1]相等&#xff0c;s[i - 1] 与 t[j - 1] 不相等两种情况具…

sudo apt install jupyter-notebook安装notebook失败E: Aborting install.

问题&#xff1a; sudo apt install jupyter-notebook安装notebook失败E: Aborting install. ~/jie/mywork/PointNetCFD$ sudo apt install jupyter-notebook --fix-missing Reading package lists... Done Building dependency tree Reading state information... Do…

第16课 核心函数(方法)

掌握常用的内置函数及其用法。 数学类函数&#xff1a;abs、divmod、max、min、pow、round、sum。 类型转换函数&#xff1a;bool、int、float、str、ord、chr、bin、hex、tuple、list、dict、set、enumerate、range、object。 序列操作函数&#xff1a;all、any、filter、m…

【1个月速成Java】基于Android平台开发个人记账app学习日记——第2天,启动项目

24.11.01 下面讲一下如何通过USB连接手机然后启动app实现真机测试&#xff0c;还是有一些坑的。 调整电脑的驱动程序&#xff0c;完成USB的连接 在启动项目的第一步我就遇见了问题&#xff0c;那就是插入usb线以后没有检测到设备。想要完成连接需要2个步骤&#xff0c;第一步…

使用Mac如何才能提高OCR与翻译的效率

OCR与截图大家都不陌生&#xff0c;或许有的朋友对于这两项功能用到的不多&#xff0c;但是如果经常会用到的话&#xff0c;那你就该看看了 iOCR&#xff0c;快捷键唤出翻译窗口&#xff0c;不论是截图翻译、划词翻译、输入翻译、剪切板翻译&#xff0c;统统快捷键完成&#x…

Etsy又被封号了!这次我终于搞懂了原因...

你是否真的了解在Etsy开店有哪些红线不能踩&#xff1f;你是否真的知道Etsy被封号后如何解决&#xff1f;本文我将探讨Etsy账号被封的常见原因&#xff0c;以及卖家可以采取的应对策略&#xff0c;以期减轻对跨境业务的伤害程度&#xff0c;感兴趣的商家速速码住&#xff0c;不…

MySQL — 事务 (o゚▽゚)o

文本目录&#xff1a; ❄️一、什么是事务&#xff1a; ❄️二、ACID特性&#xff1a; ❄️三、使用事务&#xff1a; ▶1、查看支持事务的存储引擎&#xff1a; ▶2、语法&#xff1a; ▶3、开启并且回滚&#xff1a; ▶4、开启并且提交&#xff1a; ▶ 5、保存点&#xff…

DOS时代软件遗憾落幕,国产编程新势力接过火炬

在计算机发展史上&#xff0c;DOS时代是一个不可磨灭的篇章。那个时期&#xff0c;虽然操作系统的图形界面尚未普及&#xff0c;但一款款经典软件却为我们打开了通往数字世界的大门&#xff0c;让我们在那个相对简单却充满魅力的时代中&#xff0c;感受到科技的魅力与创新的力量…

Qt的信号槽机制学习一

一、Qt理论知识简记 &#xff08;一&#xff09;信号与槽[1] 信号与槽是Qt编程的基础&#xff0c;其使得处理界面上各个组件的交互操作变得比较直观和简单&#xff0c;GUI&#xff08;Graphical User Interface&#xff09;程序设计的主要工作就是对界面上各组件的信号进行相应…

P11232 [CSP-S 2024] 超速检测

P11232 [CSP-S 2024] 超速检测 难度&#xff1a;普及/提高。 考点&#xff1a;二分、贪心。 题意&#xff1a; 题意较长&#xff0c;没有题目大意&#xff0c;否则你也大意。 主干道长度为 L L L&#xff0c;有 n n n 辆车&#xff0c;看做左端点为 0 0 0&#xff0c;第 …

使用GetX实现GetPage中间件

前言 GetX 中间件&#xff08;Middleware&#xff09;是 GetX 框架中的一种机制&#xff0c;用于在页面导航时对用户进行权限控制、数据预加载、页面访问条件设置等。通过使用中间件&#xff0c;可以有效地控制用户的访问流程&#xff0c;并在适当条件下引导用户到所需页面。 这…

JAVA:常见 JSON 库的技术详解

1、简述 在现代应用开发中&#xff0c;JSON&#xff08;JavaScript Object Notation&#xff09;已成为数据交换的标准格式。Java 提供了多种方式将对象转换为 JSON 或从 JSON 转换为对象&#xff0c;常见的库包括 Jackson、Gson 和 org.json。本文将介绍几种常用的 JSON 处理…

视频怎么去水印?7个视频去水印在线工具大比拼,宝藏工具推荐!

您是否正在寻找一款好用的视频去水印在线工具&#xff0c;却总是难以找到合适的去水印软件&#xff1f;别担心&#xff0c;今天在本文中小编将和大家分享一些去水印的小助手。很多人都觉得视频或图片上的水印十分烦人。如果您有着同样的烦恼&#xff0c;那么使用去水印工具将是…

如何一键更换ppt模板?掌握这2个ppt技巧快速搞定!

每当要制作ppt&#xff0c;很多人会第一时间去搜刮各种ppt模板&#xff0c;有时我们找到了一份貌似符合需求的模板&#xff0c;等到了ppt制作环节&#xff0c;才发现离我们的预期相距甚远&#xff0c;做到一半的ppt如何换模板呢&#xff1f; 想要在中途更换ppt模板&#xff0c;…

0基础入门linux文件系统

目录 文件系统简介 1. 文件系统类型 2. 文件系统结构 3. 文件系统的主要功能 4. 文件系统的使用 5. 文件系统的维护 6. 注意事项 简单举例 机械硬盘 物理结构介绍​编辑 CHS寻址 逻辑结构介绍 LBA寻址法 文件系统与磁盘管理 Boot Block Data block inode block…

2024年meme币走势分析:最后两个月的市场趋势与机会 #交易所#dapp#KOL社区合作

2024年即将步入尾声&#xff0c;meme币市场经历了显著的波动。对于加密市场来说&#xff0c;年底的走势尤为关键&#xff0c;尤其是meme币这种受市场情绪影响较大的加密资产。本文将从市场环境、宏观经济因素、投资者情绪、技术分析等方面分析meme币在2024年最后两个月的潜在走…