Django+channels+VUE实现即时通讯
VUE比较简单
<template>
<div style="height:90%">
<el-container style="height:100%">
<!-- <el-header>Header</el-header> -->
<el-main style="height:90%">
<div v-for="(item,index) in list" :key="index">
<div v-if="item.user==user" style="width:100%;text-align:right;">
<el-tag>{{item.value}}</el-tag>
<el-avatar size="small" :src="circleUrl"></el-avatar>
</div>
<div v-else style="width:100%;">
<el-avatar size="small" :src="circleUrl"></el-avatar>
<el-tag>{{item.value}}</el-tag>
</div>
</div>
</el-main>
<el-footer>
<el-row>
<el-col :span="22">
<el-input type="textarea" :rows="1" placeholder="请输入内容" v-model="textarea">
</el-input>
</el-col>
<el-col :span="2">
<el-button @click="mysend(textarea)">发送</el-button>
</el-col>
</el-row>
</el-footer>
</el-container>
</div>
</template>
<script>
export default {
name: "staff_service",
data() {
return {
room: "",
user: "",
list: [],
textarea: "",
webSocket: null,
circleUrl: "https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png",
};
},
methods: {
mysend() {
//发送链接请求
let _this=this
if (_this.textarea == "") {
return
}
console.log(_this.webSocket.readyState);
_this.webSocket.send(_this.textarea);
_this.textarea = ""
}
},
mounted() {
var _this = this
_this.room = JSON.parse(this.$route.query.room);
_this.user = JSON.parse(this.$route.query.user);
//判断浏览器是否支持websocket
if ("WebSocket" in window) {
console.log("支持");
_this.webSocket = new WebSocket("ws://127.0.0.1:8000/myapi/ws/chat/" + _this.room + "/" + _this.user + "/");
_this.webSocket.onopen = function (event) {
console.log("event",event);
_this.webSocket.send('text');
};
_this.webSocket.onmessage = function (msg) {
console.log(msg.data);
console.log(JSON.parse(msg.data).message);
_this.list.push(JSON.parse(msg.data).message)
};
_this.webSocket.onClose = function (msg) {
console.log("链接已经关闭",msg);
};
_this.webSocket.onError = function (err) {
console.log(err);
}
}
}
}
</script>
<style scoped>
</style>
Django安装channels和redis模块
pip install channels channels-redis
settings.py
ASGI_APPLICATION = '项目名称.asgi.application'
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
# "hosts": [('IP', 端口号)],
"hosts": ["redis://:密码@IP:端口号/0"],
"symmetric_encryption_keys": [SECRET_KEY]
},
},
}
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://IP:端口号", # 安装redis的主机的 IP 和 端口
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"CONNECTION_POOL_KWARGS": {
"max_connections": 1000,
"encoding": 'utf-8'
},
"PASSWORD": "密码" # redis密码有密码就设置
}
}
}
settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'应用程序名称',
'channels',
]
asgi.py
import os
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
from channels.auth import AuthMiddlewareStack
import myapi.routing
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'wyy.settings')
django_application = get_asgi_application()
application = ProtocolTypeRouter({
"http": get_asgi_application(),
"websocket": AuthMiddlewareStack(
URLRouter(
myapi.routing.websocket_urlpatterns
)
),
})
应用程序/routing.py.py
from django.urls import re_path
from . import consumers
websocket_urlpatterns = [
re_path(r'ws/chat/(?P<room_name>\w+)/(?P<user_name>\w+)/$', consumers.ChatConsumer.as_asgi()),
]
应用程序/consumers.py
import json
from channels.generic.websocket import AsyncWebsocketConsumer
class ChatConsumer(AsyncWebsocketConsumer):
async def connect(self):
# 创建连接时调用
self.room_name = self.scope['url_route']['kwargs']['room_name']
self.user_name = self.scope['url_route']['kwargs']['user_name']
self.room_group_name = 'chat_%s' % self.room_name
print('roomname', self.room_name)
print('user_name', self.user_name)
# 将新的连接加入到群组
await self.channel_layer.group_add(
self.room_group_name,
self.channel_name
)
await self.accept()
async def disconnect(self, close_code):
# 连接关闭时调用
await self.channel_layer.group_discard(
self.room_group_name,
self.channel_name
)
# Receive message from WebSocket
async def receive(self, text_data):
# 收到信息时调用
# print(1)
print(type(text_data), text_data)
# text_data_json = json.loads(text_data)
# print(text_data_json)
# message = text_data_json['message']
# 信息群发
await self.channel_layer.group_send(
# text_data
self.room_group_name,
{
'type': 'chat_message',
# 'message': '{"'+self.user_name + '":"' + text_data+'"}'
'message': {'user': self.user_name,
'value': text_data}
}
)
# Receive message from room group
async def chat_message(self, event):
message = event['message']
# Send message to WebSocket
await self.send(text_data=json.dumps({
'message': message
}))