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插件配置
通过websocket进行长链接通信
django中channel模块之websocket_10973441的技术博客_51CTO博客
WebSocket是一种在单个TCP连接上进行全双工通信的协议
在WebSocket协议中,没有Request和Response的概念,连接一旦建立,就建立了持久连接,双方可以随时向对方发送数据
全双工:
通信允许数据在两个方向上同时传输。
全双工可以同时进行信号的双向传输,即A-->B的同时B-->A,是瞬间同步的。
日常生活中的电话聊天就是全双工。
半双工:
可分时进行信号的双向传输。
指A-->B时,不能B-->A。
数据可以双向传输,但双向传输不是同时进行的。
例如对讲机,一方讲话的同时,另一方不能讲话。
单工:
单向的数据传输。
只允许A-->B传送消息,不能B-->A传送。
例如日常生活中的广播。
在WebSocket概念出来之前,如果页面要不停地显示最新的价格,那么必须不停地刷新页面,或者用一段js代码每隔几秒钟发消息询问服务器数据。
而使用WebSocket技术之后,当服务器有了新的数据,会主动通知浏览器。 如当服务端有新的比特币价格之后,浏览器立马接收到消息。
HTTP协议是浏览器客户端发出请求,服务端进行响应,服务端不能主动发送信息到客户端。
WebSocket协议区别于HTTP协议的最大特点,即WebSocket可以由服务端主动发送消息到浏览器端。
最普遍的应用就是tail -f查看服务器端的日志,可实现动态刷新最新日志。
WebSocket的另外一个应用场景就是聊天室,一个浏览器端发送的消息,其他浏览器端可同时接受。这在HTTP协议下很难实现的。
django可以通过channels或者dwebsocket去实现,但是dwebsocket不支持django3.x,所以使用channels来实现前后端的通信
Django-channels2.0笔记--2、Channel Layers - 简书
pip install channels==3.0.4
pip install channels_redis
注册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', # <-----这里
]
这里为什么用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.
import os
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
from . 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),
})
from django.urls import path
from dyz_account.consumers import ChatConsumer
websocket_urlpatterns = [
path('ws/chat', ChatConsumer.as_asgi()),
]
import json
from channels.generic.websocket import WebsocketConsumer
from channels.exceptions import StopConsumer
CONN_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()
1.这是个普通(群聊)的写法
群聊2 ----只基于vue2
这需要什么配置都写在图片下面
第二种实现方式是基于channels中提供channel layers来实现
1.先建立连接
2.浏览器websocket向后端发送数据
如果是add_chat 添加所输入的群号
如果是不add_chat 则获取前端传给后端的信息去发送
3.要么不发送消息的时候断开连接 把群号从channel_layer 中移除
from channels.generic.websocket import WebsocketConsumer
from channels.exceptions import StopConsumer
from asgiref.sync import async_to_sync
import json
class 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()
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写法
9.写到这个里就结束的了,上面的比较专业我复制了链接了,需要的去看看哟