Django结合websocket实现分组的多人聊天

其他地方和上一篇大致相同,上一篇地址点击进入,

改动点1:在setting.py中最后再添加如下配置:

#  多人聊天
CHANNEL_LAYERS = {"default":{"BACKEND": "channels.layers.InMemoryChannelLayer"}
}

因此完整的settings.py文件如下:

"""
Django settings for ws_demo project.Generated by 'django-admin startproject' using Django 4.2.For more information on this file, see
https://docs.djangoproject.com/en/4.2/topics/settings/For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.2/ref/settings/
"""from pathlib import Path# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-&62q15t&-it1jwy4o^&xsh(!fj3cm)#7=r+z12yw3j@x@kox2x'# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = TrueALLOWED_HOSTS = []# Application definitionINSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles',"channels",  # 添加channels"app01.apps.App01Config" # 添加app01
]MIDDLEWARE = ['django.middleware.security.SecurityMiddleware','django.contrib.sessions.middleware.SessionMiddleware','django.middleware.common.CommonMiddleware','django.middleware.csrf.CsrfViewMiddleware','django.contrib.auth.middleware.AuthenticationMiddleware','django.contrib.messages.middleware.MessageMiddleware','django.middleware.clickjacking.XFrameOptionsMiddleware',
]ROOT_URLCONF = 'ws_demo.urls'TEMPLATES = [{'BACKEND': 'django.template.backends.django.DjangoTemplates','DIRS': [],'APP_DIRS': True,'OPTIONS': {'context_processors': ['django.template.context_processors.debug','django.template.context_processors.request','django.contrib.auth.context_processors.auth','django.contrib.messages.context_processors.messages',],},},
]WSGI_APPLICATION = 'ws_demo.wsgi.application'# Database
# https://docs.djangoproject.com/en/4.2/ref/settings/#databasesDATABASES = {'default': {'ENGINE': 'django.db.backends.sqlite3','NAME': BASE_DIR / 'db.sqlite3',}
}# Password validation
# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validatorsAUTH_PASSWORD_VALIDATORS = [{'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',},{'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',},{'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',},{'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',},
]# Internationalization
# https://docs.djangoproject.com/en/4.2/topics/i18n/LANGUAGE_CODE = 'en-us'TIME_ZONE = 'UTC'USE_I18N = TrueUSE_TZ = True# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.2/howto/static-files/STATIC_URL = 'static/'# Default primary key field type
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-fieldDEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'ASGI_APPLICATION = "ws_demo.asgi.application"#  多人聊天
CHANNEL_LAYERS = {"default":{"BACKEND": "channels.layers.InMemoryChannelLayer"}
}

2、app01下view.py中的内容如下:

from django.shortcuts import render
# Create your views here.def index(request):qq_group_num = request.GET.get("num")return render(request, 'index.html', {"qq_group_num": qq_group_num})

3、index.html中的内容如下:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><style>.message {height: 300px;border: 1px solid #dddddd;width: 100%;}</style>
</head><body>
<div class="message" id="message"></div>
<div><input type="text" placeholder="请输入" id="txt"><input type="button" value="发送" onclick="sendMsg()"><input type="button" value="关闭连接" onclick="closeConn()"><input type="button" value="重新建立连接" onclick="connect()">
</div><script>var socket = null;function connect() {socket = new WebSocket("ws:/127.0.0.1:8000/room/{{qq_group_num}}/");// 连接完成以后 客户端自动触发socket.onopen = function (event) {let tag = document.createElement("div")tag.innerHTML = "连接已建立"document.getElementById("message").appendChild(tag)}// 回调函数 当服务端有消息发送到时,自动触发socket.onmessage = function (event) {console.log(event.data);let tag = document.createElement("div");tag.innerText = event.data;document.getElementById("message").appendChild(tag)}// 当连接关闭时,触发socket.onclose = function (event) {let tag = document.createElement("div")tag.innerHTML = "连接已断开"document.getElementById("message").appendChild(tag)}}function sendMsg() {let tag = document.getElementById("txt")socket.send(tag.value)}function closeConn() {// 向服务端发送断开连接socket.close();}connect()
</script>
</body>
</html>

consumers.py中的内容如下:

from channels.generic.websocket import WebsocketConsumer
from channels.exceptions import StopConsumer
from asgiref.sync import async_to_syncclass ChatConsumer(WebsocketConsumer):  # 继承WebsocketConsumerdef websocket_connect(self, message):print("有人进行连接了。。。。")# 有客户端向后端发送 WebSocket 连接的请求时,自动触发(握手)self.accept()#  获取群号,获取路由匹配中的群号group = self.scope["url_route"]["kwargs"].get("group")# 将这个客户端连接对象加入到某个组里边(内存 or redis) async_to_sync 将异步方法转换为同步方法async_to_sync(self.channel_layer.group_add)(group, self.channel_name)def websocket_receive(self, message):# 浏览器基于 WebSocket 向后端发送数据,自动触发接收消息print(message)group = self.scope["url_route"]["kwargs"].get("group")# #  一对一聊天# if message["text"] == "close":#     self.send("服务端主动关闭连接")#     #  服务端主动关闭连接#     self.close()# self.send(message["text"])# 通知组内的所有客户端,执行xx_oo方法,在此方法中自己可以去定义任意的功能 下边是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.rhkb.cn/news/490143.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络工程师常用软件之配置对比软件

老王说网络&#xff1a;网络资源共享汇总 https://docs.qq.com/sheet/DWXZiSGxiaVhxYU1F ☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝ 我们经常在项目或者运维中对设备的config进行变更&am…

Spring Boot 集成 MyBatis 全面讲解

Spring Boot 集成 MyBatis 全面讲解 MyBatis 是一款优秀的持久层框架&#xff0c;与 Spring Boot 集成后可以大大简化开发流程。本文将全面讲解如何在 Spring Boot 中集成 MyBatis&#xff0c;包括环境配置、基础操作、高级功能和最佳实践。 一、MyBatis 简介 1. SqlSession …

面向对象编程(下半)

面向对象编程&#xff08;下半&#xff09; 继承 面向对象的三大特征: 封装&#xff0c;继承&#xff0c;多态 继承的作用&#xff1f;能解决什么样的实际问题&#xff1f; 生活中的继承&#xff1a;将一方所拥有的东西给予另一方。父母的财富 类之间的继承&#xff1a;属性…

Python 给 Excel 写入数据的四种方法

Python 在数据处理领域应用广泛&#xff0c;其中与 Excel 文件的交互是常见需求之一。 本文将介绍四种使用 Python 给 Excel 文件写入数据的方法&#xff0c;并结合生活中的例子进行解释&#xff0c;帮助新手小白快速上手。 1. 使用 openpyxl 库 openpyxl 是一个用于读写 Exc…

Vue3项目的创建与使用

Vue 有 Vue2 和 Vue3 &#xff0c;因为 Vue2 已经停止维护&#xff0c;所以我是直接从 Vue3 开始学习的。 Vue 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML 、 CSS 和 JavaScript 构建&#xff0c;并提 供了一套声明式的、组件化的编程模型&#xff0c;帮…

2024 年最新前端ES-Module模块化、webpack打包工具详细教程(更新中)

模块化概述 什么是模块&#xff1f;模块是一个封装了特定功能的代码块&#xff0c;可以独立开发、测试和维护。模块通过导出&#xff08;export&#xff09;和导入&#xff08;import&#xff09;与其他模块通信&#xff0c;保持内部细节的封装。 前端 JavaScript 模块化是指…

第十三周Scrum Meeting记录

组长&#xff1a; 张楷 副组长&#xff1a;王骏 小组成员&#xff1a;林佳欣 王文秋 李昌豪 陈俊泽 赵浩然 项目链接&#xff1a;https://github.com/ctrlshiftm129/Tuanzi 文章目录 个人工作记录燃尽图组会照片代码签入记录本周总结 个人工作记录 成员工作内容张楷完成了从…

Linux 磁盘满了怎么办?快速排查和清理方法

当 Linux 磁盘满了&#xff0c;会导致系统无法正常运行&#xff0c;比如无法写入文件、服务停止、甚至系统崩溃。因此&#xff0c;快速排查并清理磁盘空间是非常重要的。以下是详细的排查和解决步骤&#xff1a; 一、快速定位磁盘占用原因 1. 检查磁盘使用情况 使用 df 命令查…

中科网威-anysec安全网关 arping 远程命令执行漏洞复现(CNVD-2024-46119)

0x01 产品简介 深圳市中科网威科技有限公司成立于深圳市南山科技园信息产业化基地(也有说法称总部位于深圳市福田国际电子商务产业园),是深圳市高新技术企业、双软企业。公司致力于VPN防火墙、流量监控、网络行为管理、ANYSEC安全网关、IT运维设备等前沿网络设备的研发、生…

什么是PCB的CAF效应?

导电阳极丝&#xff08;CAF&#xff09;现象及其影响 在高科技电子产品制造中&#xff0c;尤其是在对环境适应性要求极高的汽车电子和军工领域&#xff0c;产品的耐高温和高湿性能显得尤为重要。 随着电子产品向更高集成度发展&#xff0c;电路板上的孔间距不断缩小&#xff…

harbor镜像仓库搭建

Harbor简介 Harbor的发展背景和现状 Harbor项目起始于2014年左右,当时正值容器技术和微服务架构迅速崛起的时期。随着越来越多的企业开始采用容器化部署应用,对于私有镜像管理的需求也日益增长。传统的解决方案要么缺乏必要的企业级特性(如访问控制、安全性和可扩展性),…

【数据结构——查找】顺序查找(头歌实践教学平台习题)【合集】

目录&#x1f60b; 任务描述 相关知识 测试说明 我的通关代码: 测试结果&#xff1a; 任务描述 本关任务&#xff1a;实现顺序查找的算法。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a;1.根据输入数据建立顺序表&#xff0c;2.顺序表的输出&#xff0c;…

UOB大华银行|校招网申综合能力SHL测评题库英语版本真题分析

大华银行有限公司&#xff08;大华银行&#xff09;是亚洲银行业的翘楚&#xff0c;大华银行总部位于新加坡&#xff0c;并在中国、印度尼西亚、马来西亚、泰国及越南设立了全资法人银行&#xff0c;在全球拥有约500 间分行及办事处&#xff0c;分布在亚太、欧洲与北美的19 个国…

[C#与C++交互] 跨进程通信NamedPipes

目录 1、前言 2、什么是命名管道&#xff1f; 3、实现步骤 4、示例代码 4.1 C 服务器代码 4.2 C# 客户端代码 5、运行步骤 6、注意事项 7、应用场景 8、优缺点 9、总结 1、前言 在 C# 和 C 应用程序之间进行数据交换时&#xff0c;命名管道&#xff08;Named Pipes…

《宇宙机器人》提示错误弹窗“找不到d3dx9_43.dll”是什么原因?“d3dx9_43.dll缺失”怎么解决?

电脑游戏运行时常见问题解析&#xff1a;《宇宙机器人》提示“找不到d3dx9_43.dll”的解决之道 TGA2024落幕&#xff0c;年度最佳游戏——《宇宙机器人》&#xff0c;作为一名在软件开发领域深耕多年的从业者&#xff0c;我深知电脑游戏在运行过程中可能会遇到的各种挑战&…

Hive-4.0.1数据库搭建(可选配置用户名密码远程连接)

1.官网下载tar包上传到服务器并解压&#xff08;我这里解压到了hive目录): 2.进入到conf目录&#xff0c;并复制模板配置文件进行修改&#xff1a; cd /apache-hive-4.0.1-bin/conf cp hive-default.xml.template hive-site.xml3.编写内容如下&#xff1a; <property>&…

计算机内存里面4个字节与float类型数据的转换原理

在计算机科学中&#xff0c;四个字节与float&#xff08;单精度浮点数&#xff09;之间的转换是一种常见的操作。这种转换涉及到数据类型的转换和内存存储的相关知识&#xff0c;其原理主要基于IEEE 754标准。以下是对四个字节和float转换原理的详细解释&#xff1a; 一、基本…

MATLAB 识别色块和数量

文章目录 前言步骤 1: 读取图像步骤 2: 转换为 HSV 颜色空间步骤 3: 定义颜色范围步骤 4: 创建颜色掩码步骤 5: 应用形态学操作&#xff08;可选&#xff09;步骤 6: 标记和显示结果完整代码步骤七 返回色块坐标 总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&…

抓包分析DHCP的工作过程

一、DHCP简介 DHCP&#xff08;Dynamic Host Configuration Protocol&#xff09;动态主机配置协议&#xff0c;前身是BOOTP协议。在大型局域网中&#xff0c;需要给很多主机配置地址信息&#xff0c;如果采用传统手工配置&#xff08;累死&#xff09;&#xff0c;效率太低&am…

MUR3060PTR-ASEMI快恢复二极管对管MUR3060PTR

编辑&#xff1a;ll MUR3060PTR-ASEMI快恢复二极管对管MUR3060PTR 型号&#xff1a;MUR3060PTR 品牌&#xff1a;ASEMI 封装&#xff1a;TO-247 正向电流&#xff1a;30A 反向电压&#xff1a;600V 正向压降&#xff1a;0.98V~1.90V 引线数量&#xff1a;3 芯片个数&a…