1.如何实现聊天功能

2.什么是websocket

2.1解释什么叫全双工,半双工,单工

3.websocker的概念

4.websocket的优点

5.django ,vue如何实现websocket

6.django配置

6.1安装channels,安装channels_redis

6.2 配置channels

6.3在settings.py 中配置asgi

6.4 在settings.py 中创建routing.py

6.5创建consumer.py文件,处理websocket通信逻辑

7.前端进行websoket链接(群聊1 vue3,vue2也可以用)

8.群聊2 如图片所示(只能vue2)

8.1创建consumer.py文件,处理websocket通信逻辑

8.2前端chat_ui插件配置

1.如何实现聊天室功能

通过websocket进行长链接通信

2.什么是websocket

django中channel模块之websocket_10973441的技术博客_51CTO博客

WebSocket是一种在单个TCP连接上进行全双工通信的协议

在WebSocket协议中,没有Request和Response的概念,连接一旦建立,就建立了持久连接,双方可以随时向对方发送数据

2.1 解释下什么叫全双工,半双工,单工

全双工:
通信允许数据在两个方向上同时传输。
全双工可以同时进行信号的双向传输,即A-->B的同时B-->A,是瞬间同步的。
日常生活中的电话聊天就是全双工。

半双工:
可分时进行信号的双向传输。
指A-->B时,不能B-->A。
数据可以双向传输,但双向传输不是同时进行的。
例如对讲机,一方讲话的同时,另一方不能讲话。

单工:
单向的数据传输。
只允许A-->B传送消息,不能B-->A传送。
例如日常生活中的广播。

3.websocket的概念

在WebSocket概念出来之前,如果页面要不停地显示最新的价格,那么必须不停地刷新页面,或者用一段js代码每隔几秒钟发消息询问服务器数据。

而使用WebSocket技术之后,当服务器有了新的数据,会主动通知浏览器。 如当服务端有新的比特币价格之后,浏览器立马接收到消息。

4.websocket的优点

HTTP协议是浏览器客户端发出请求,服务端进行响应,服务端不能主动发送信息到客户端。
WebSocket协议区别于HTTP协议的最大特点,即WebSocket可以由服务端主动发送消息到浏览器端。
最普遍的应用就是tail -f查看服务器端的日志,可实现动态刷新最新日志。
WebSocket的另外一个应用场景就是聊天室,一个浏览器端发送的消息,其他浏览器端可同时接受。这在HTTP协议下很难实现的。

5.django ,vue 如何实现websoket

django可以通过channels或者dwebsocket去实现,但是dwebsocket不支持django3.x,所以使用channels来实现前后端的通信

Django-channels2.0笔记--2、Channel Layers - 简书

6.django配置

6.1安装channels,channels_redis

pip install channels==3.0.4pip install channels_redis

6.2配置channels

注册channels

INSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','corsheaders','rest_framework','account','rest_framework.authtoken','drf_yasg2','channels', # <-----这里
]

6.3在setting中配置asgi

这里为什么用asgi不用wsgi,因为wsgi不支持websocket通信。

# Django项目默认的WSGI配置,可以注释掉,也可以放着不管,因为之后我们不会使用WSGI作为网关,而是使用下面的ASGI配置。

# 增加ASGI配置

注意:提前查看下自己redis的版本

连接redis-cli

输入info

有个server 下面显示版本5.0以上,可以使用

WSGI_APPLICATION = 'dyz_account.wsgi.application'
ASGI_APPLICATION = 'dyz_account.asgi.application'CHANNEL_LAYERS = {'default': {'BACKEND': 'channels_redis.core.RedisChannelLayer','CONFIG': {# 连接自己的redis"hosts": [('101.42.224.35', 6379)],},},
}

然后,在项目的settings.py同级目录下的asgi.py文件中加入下面的内容:

Django2.2是默认没有asgi.py文件,手动创建一个即可。

Django3之后,项目默认会生成一个asgi.py文件, 默认的asgi虽然支持了异步服务,但是仍然不支持websocket.

django3修改asgi.py文件

import os
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouterfrom . import routing
from channels.auth import AuthMiddlewareStack
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'dyz_account.settings')application = ProtocolTypeRouter({"http": get_asgi_application(),"websocket": AuthMiddlewareStack(URLRouter(routing.websocket_urlpatterns)),
})

Django2.2不支持asgi,因此无法从django.core.asgi导入get_asgi_application,需要使用如下配置。

import os
import django
from channels.http import AsgiHandler
from channels.routing import ProtocolTypeRouter,URLRouter
from . import routing      # 这个文件后续会说,你先写上。os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'dayuanzhong.settings')
django.setup()application = ProtocolTypeRouter({"http": AsgiHandler(),"websocket": URLRouter(routing.websocket_urlpatterns),
})

6.4在settings同级目录中创建routing.py,注册路由

from django.urls import path
from dyz_account.consumers import ChatConsumerwebsocket_urlpatterns = [path('ws/chat', ChatConsumer.as_asgi()),
]

6.5创建consumer.py文件,处理websocket通信逻辑

import jsonfrom channels.generic.websocket import WebsocketConsumer
from channels.exceptions import StopConsumerCONN_LIST = []class ChatConsumer(WebsocketConsumer):def websocket_connect(self, message):print("开始链接...")# 有客户端来向后端发送websocket连接的请求时,自动触发。# 服务端允许和客户端创建连接(握手)。self.accept()CONN_LIST.append(self)def websocket_receive(self, message):# 浏览器基于websocket向后端发送数据,自动触发接收消息。print('接受的消息', message)text = message['text']  # {'type': 'websocket.receive', 'text': '阿斯蒂芬'}print("接收到消息-->", text)res = {'result': 'ok'}for conn in CONN_LIST:conn.send(json.dumps(res))def websocket_disconnect(self, message):CONN_LIST.remove(self)raise StopConsumer()

7、前端进行websocket链接(群聊1)

1.这是个普通(群聊)的写法

<template><div style="    width: 60%;margin-left: 20%;"><div class="message" id="message"></div><div><input type="text" placeholder="请输入" id="txt" v-model="send_data"><input type="button" value="发送" @click="sendMessage(send_data)"><input type="button" value="关闭连接" @click="closeConn()"></div></div></template><script>
import Axios from 'axios'
// import { } from "@/components/axios_api/api.js"; // @符号指的是src路径
export default {data() {return {send_data: ''};},components: {},methods: {initWebSocket() {//初始化websocket      var wsuri = "ws://127.0.0.1:8000";// var ws_scheme = window.location.protocol === "https:" ? "wss" : "ws";var ws_on_line = wsuri + '/ws/chat'// 本地走代理/vue.config.js,线上也代理nginx代理console.log('111111111111', ws_on_line)// var ws_scheme = window.location.protocol==="https:"?"wss":"ws"      this.websock = new WebSocket(ws_on_line);this.websock.onopen = this.websocketonopen;this.websock.onmessage = this.websocketonmessage;this.websock.onerror = this.websocketonerror;// this.websock.onclose = this.websocketclose;   },websocketonopen() {//连接建立之后执行send方法发送数据     console.log("建立连接");var actions = { message: "连接测试" };this.sendMessage(actions);},websocketonerror(e) {//连接建立失败重连      console.log("连接error", e);// this.initWebSocket();},websocketonmessage(e) {//数据接收      this.websocket_data = JSON.parse(e.data);console.log("websocket-res", JSON.stringify(this.websocket_data))console.log("接收后端数据type", typeof (this.websocket_data))// 将websocket消息展示在消息提示框     var h = this.$createElement;// 创建html元素      this.hrender = h("p", null, [h("div", [h("div",JSON.stringify(this.websocket_data.message)),// 传变量           //   },         // }),           ],null),]);},sendMessage(Data) {//数据发送     this.websock.send(JSON.stringify(Data));},websocketclose(e) {  //关闭      console.log('断开连接', e);},closeConn(){socket.close(); // 向服务端发送断开连接的请求}},mounted() {this.initWebSocket()},
};
</script><style>
</style>

8.主要实现图片(别人发的消息在左边,自己发送的消息在右边)

群聊2 ----只基于vue2

这需要什么配置都写在图片下面

 第二种实现方式是基于channels中提供channel layers来实现

1.先建立连接

2.浏览器websocket向后端发送数据

如果是add_chat  添加所输入的群号

如果是不add_chat  则获取前端传给后端的信息去发送

3.要么不发送消息的时候断开连接 把群号从channel_layer 中移除

8.1创建consumer.py文件,处理websocket通信逻辑


from channels.generic.websocket import WebsocketConsumer
from channels.exceptions import StopConsumer
from asgiref.sync import async_to_sync
import jsonclass ChatConsumer(WebsocketConsumer):def websocket_connect(self, message):# 接收这个客户端的连接self.accept()# 将这个客户端的连接对象加入到某个地方(内存 or redis)1314 是群号这里写死了# async_to_sync(self.channel_layer.group_add)(1314, self.channel_name)def websocket_receive(self, message):# 浏览器基于websocket向后端发送数据,自动触发接收消息print('222', message) data = json.loads(message['text'])chat_type = data.get('chat_type')chat_id = data.get('chat_id')chat_content = data.get('message')print('chat_type', chat_type)if chat_type == 'add_chat':async_to_sync(self.channel_layer.group_add)(chat_id, self.channel_name)# 通知组内的所有客户端,执行 chat_message 方法,在此方法中自己可以去定义任意的功能。async_to_sync(self.channel_layer.group_send)(chat_id, {"type": 'chat.message', 'message': message})# 这个方法对应上面的type,意为向1314组中的所有对象发送信息# 回调的方法def chat_message(self, event):text = event['message']['text']self.send(text)def websocket_disconnect(self, message):print('3333', message)data = json.loads(message['text','{}'])chat_id = data.get('chat_id')# 断开链接要将这个对象从 channel_layer 中移除async_to_sync(self.channel_layer.group_discard)(chat_id, self.channel_name)raise StopConsumer()

8.2 前端chat_ui插件配置

1.安装

npm install @maybecode/m-chat

2.vue中main.js添加

import Vue from 'vue'
import MChat from '@maybecode/m-chat'Vue.use(MChat)

3.局部使用

import MChat from '@maybecode/m-chat'export default {components: {MChat}
}

4.具体的解释看官方 :m-chat: 基于vue 聊天(IM) UI组件

5.前端vue2写法

<template><div style="width: 60%; margin-left: 20%"><div class="message" id="message"></div><div v-show="add_chat"><inputtype="text"placeholder="请输入群聊id"id="txt"v-model="chat_id"/><input type="button" value="加入群聊" @click="addChat()" /></div><div v-show="send_chat"><m-chatref="mChat":messages="messages"@submit="submit":loadMore="loadMore"height="100vh":openExtends="open_extends"></m-chat></div></div>
</template><script>
// import { } from "@/components/axios_api/api.js"; // @符号指的是src路径
import MChat from "@maybecode/m-chat";
export default {data() {return {user_id: "",send_data: "",chat_id: null,send_chat: false,add_chat: true,messages: [],open_extends: ["image"],};},components: {MChat,},methods: {submit(content) {this.sendMessage(content["content"]);},loadMore() {},// 加入群聊,如果有对应的id,进入群聊,没有则创建一个新的群聊addChat() {//获取存入的user_id// 如果没有就跳转到登录页面var userid = localStorage.getItem("user_id");if (userid) {if (this.chat_id) {this.initWebSocket();this.send_chat = true;this.add_chat = false;} else {alert("请输入群聊号");}}else{alert('拜拜')this.$router.push('/login')}},initWebSocket() {//初始化websocket----连接后端var wsuri = "ws://192.168.10.20:8000";// var ws_scheme = window.location.protocol === "https:" ? "wss" : "ws";var ws_on_line = wsuri + "/ws/chat";// 本地走代理/vue.config.js,线上也代理nginx代理console.log("111111111111", ws_on_line);// var ws_scheme = window.location.protocol==="https:"?"wss":"ws"this.websock = new WebSocket(ws_on_line);this.websock.onopen = this.websocketonopen;this.websock.onmessage = this.websocketonmessage;this.websock.onerror = this.websocketonerror;// this.websock.onclose = this.websocketclose;},websocketonopen() {//连接建立之后执行send方法发送数据console.log("建立连接");var actions = { message: "连接测试" };var type = "add_chat";this.sendMessage(actions, type);},websocketonerror(e) {//连接建立失败重连console.log("连接error", e);// this.initWebSocket();},websocketonmessage(e) {//数据接收//json.parse()服务器一般接受的是js对象  this.websocket_data = JSON.parse(e.data);//json.stringfy 是将接js对象转换为json数据console.log("websocket-res", JSON.stringify(this.websocket_data));console.log("接收后端数据type", typeof this.websocket_data);//获取信息里面的user_id,然后把消息放入左边let message_user_id = this.websocket_data["user_id"];let message_self = false;// 判断当前消息是否自己发出if (message_user_id == localStorage.getItem("user_id")) {message_self = true;}else{message_self=false}// 获取信息里面的usrnamelet name = this.websocket_data.username;// 将websocket消息展示在消息提示框var count = this.messages.length;var push_message = {type: "text",content: { text: JSON.stringify(this.websocket_data.message) },id: count + 1,self: message_self,name: name,};this.messages.push(push_message);var h = this.$createElement;// 创建html元素this.hrender = h("p", null, [h("div",[h("div", JSON.stringify(this.websocket_data.message)),// 传变量//   },// }),],null),]);},sendMessage(Data, type = "send_data") {//数据发送console.log("222222222222");this.websock.send(JSON.stringify({chat_id: this.chat_id,message: Data,chat_type: type,// 获取里面存的username,user_idusername: localStorage.getItem("username"),user_id: localStorage.getItem("user_id"),}));},websocketclose(e) {//关闭console.log("断开连接", e);},userinfo() {},},mounted() {},
};
</script><style>
</style>

9.写到这个里就结束的了,上面的比较专业我复制了链接了,需要的去看看哟

django+vue3实现websocket聊天室(群聊)相关推荐

  1. Java WebSocket实现网络聊天室(群聊+私聊)

    WebChat聊天室 2018.02.26 源码地址早就贴了呀, 留邮箱不如自己下载 项目地址: https://github.com/Amayadream/WebChat 2017.01.11更新 ...

  2. Netty中实现多客户端连接与通信-以实现聊天室群聊功能为例(附代码下载)

    场景 Netty的Socket编程详解-搭建服务端与客户端并进行数据传输: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/1086 ...

  3. java仿QQ聊天室群聊(快速写一个简易QQ)

    [mie haha的博客]转载请注明出处(万分感谢!): https://blog.csdn.net/qq_40315080/article/details/83052689 用java写聊天室实现群 ...

  4. java仿qq群聊_[转载]仿QQ聊天室群聊的练习心得

    javase的学习即将告一段落,作为最后的一个项目练习,仿聊天室的程序编写让我很是头疼了一阵子.说起来还是自己java基础不牢的缘故导致的,虽然整体框架都已经很清晰了但是实际编写过程中却依然磕磕绊绊, ...

  5. springboot和netty整合的聊天室--群聊

    一.创建项目 file-new-project-spring initializr-next 然后 添加这两个依赖 二.代码 DemoApplication package com.example.d ...

  6. 当年的聊天室,今天的我(java实现聊天室群聊功能)

    预备小知识连接: 小小聊天室,慢慢的回忆啊!(TCP 通信实现) 先看效果 主要可以分为三个层:服务端层,客户端层,还有就是工具层: 服务断层:包括接收数据,以及转发数据(数据输出输入流): 客户端层 ...

  7. PHP+AJAX高性能聊天室(群聊+私聊)

    无需服务端 Anlin_chat 一个多功能免费开源的网页聊天室,基于php+mysql+js运行 无需服务端,高效+极快的运行速度 (超高安全性)支持分类帖子推送兼容QQ内置,微信内置,Firefo ...

  8. BIO聊天室(群聊+私聊)

    功能:群聊+私发+上线提醒+下线提醒+查询在线用户 文件 Utils FinalValue Message Server Client Receive Send Utils package morem ...

  9. java控制层创建websocket_用Java构建一个简单的WebSocket聊天室

    前言 首先对于一个简单的聊天室,大家应该都有一定的概念了,这里我们省略用户模块的讲解,而是单纯的先说说聊天室的几个功能:自我对话.好友交流.群聊.离线消息等. 今天我们要做的demo就能帮我们做到这一 ...

最新文章

  1. 百度重置页面自动跳转脚本
  2. nginx 之负载均衡 :PHP session 跨多台服务器配置
  3. Microservices Reference Architecture - with Spring Boot, Spring Cloud and Netflix OSS--转
  4. Discuz!NT 模板机制分析(转)
  5. 直接进入ORACLE12C插件数据库
  6. Boost-QT兼容问题:#define FUSION_HASH #
  7. 测试工具iometer, iozone, bonnie++
  8. angular ng-href
  9. Emmet:HTML/CSS代码快速编写神器
  10. 【信息论】信息论基础知识
  11. 搬运: CVonline: 图像数据库(二) (更新于20190821)
  12. Gspay 和 95epay
  13. hadoop生态系统的详细介绍-详细一点
  14. 人工智能被批不环保,训练一个神经网络的排炭量竟然比5辆车还多?
  15. 如何重写equals方法
  16. 图解迪士尼发展史:华特·迪士尼建立的动画王国
  17. AE快速批量添加字幕
  18. 成就系统和任务系统的设计
  19. 《浪潮之巅》2蓝色巨人 IBM公司
  20. epic服务器状态,对 Epic Games 启动程序问题进行故障排除

热门文章

  1. About 10.30 This Week
  2. 2021机动车检测站签字授权人法律法规和规范考试题库及答案
  3. 融资 30 亿元后,李想坦承了他最大的恐惧
  4. 麒麟操作系统+龙心 编译qt-arm
  5. 选购ERP软件时需避免的五大错误
  6. Github中如何给项目创建GitHub Pages官方网页
  7. 签约冯小刚徐帆代言,金立M2017能否跨越新高度?
  8. SpringBoot 操作 ES 进行各种高级查询
  9. 2022“华为杯”(E、F题)思路分析、代码......
  10. SpringSecurity 源码解析 | 加JWT 实战 之 授权流程源码分析