DjangoChannels_vue前端搭建简易版的网页聊天功能

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: DjangoChannels_vue前端搭建简易版的网页聊天功能

效果

链接:http://yongma16.xyz:/#/onlinewebsocket
image.png
image.png

redis安装

下载redis
linux https://redis.io/
windows https://github.com/microsoftarchive/redis
设置配置文件
修改redis.conf
注释掉

# bind 127.0.0.1
# proteced-mode no

启动linux上的redis-server
在对应的目录运行

 ./redis-server ../redis.conf

image.png

redis连接

使用redismanager连接搭建的redis
已经连接
image.png

channel模块的安装引用

pip安装channel模块

pip install -U channels

添加app

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    ...
    'channels',
)

asgi.py的配置文件添加websocket协议
image.png

import os
from channels.auth import AuthMiddlewareStack
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter,URLRouter#channels的路由
import webchat.routing

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myblogsite.settings')
application=ProtocolTypeRouter(
    {
        "http":get_asgi_application(),
        #添加http协议
        "websocket": AuthMiddlewareStack(
            URLRouter(
                webchat.routing.websocket_urlpatterns
                #聊天app
            )
        ),
        #路由配置
    }
)

路由:

# chat/routing.py
from django.urls import re_path

from . import consumers
#广播消息

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

异步发送消息:

import json
from asgiref.sync import async_to_sync
from channels.generic.websocket import WebsocketConsumer
#异步请求
class ChatConsumer(WebsocketConsumer):
    def connect(self):
        self.room_name = self.scope['url_route']['kwargs']['room_name']
        self.room_group_name = 'chat_%s' % self.room_name
        # Join room group
        async_to_sync(self.channel_layer.group_add)(
            self.room_group_name,
            self.channel_name
        )
        self.accept()
    def disconnect(self, close_code):
        # Leave room group
        async_to_sync(self.channel_layer.group_discard)(
            self.room_group_name,
            self.channel_name
        )
    # Receive message from WebSocket
    def receive(self, text_data):
        text_data_json = json.loads(text_data)
        message = text_data_json['message']
        # Send message to room group
        async_to_sync(self.channel_layer.group_send)(
            self.room_group_name,
            {
                'type': 'chat_message',
                'message': message
            }
        )
    # Receive message from room group
    def chat_message(self, event):
        message = event['message']

        # Send message to WebSocket
        self.send(text_data=json.dumps({
            'message': message
        }))

验证channels

中途不报错则安装过程没问题

$ python3 manage.py shell
>>> import channels.layers
>>> channel_layer = channels.layers.get_channel_layer()
>>> from asgiref.sync import async_to_sync
>>> async_to_sync(channel_layer.send)('test_channel', {'type': 'hello'})
>>> async_to_sync(channel_layer.receive)('test_channel')
{'type': 'hello'}

vue前端访问

连接接websocket

  data () {
    return {
      msg: '测试中',
      send_info: 'test Websocket!',
      room_name: ['DjangoVue'],
      room_select: '',
      baseUrl:'http:localhost:8006/webchat/index',
      // baseUrl:'http://yongma16.xyz:8006/webchat/index',
      websocketUrl:'localhost:8006/ws/webchat/',
      // websocketUrl: 'yongma16.xyz/ws/webchat/',
      websocket: null,
      // room 存房间名字,content保存聊天信息的数组
      chat_info: [],
      chat_room:null,
      room_loc:0,
      user:'匿名用户',
      cookieValue:document.cookie
    }
  },
  watch(){
    // cookieValue:function(newValue,oldValue){
    //   this.user=newValue
    //   console.log(newValue,oldValue)
    //   return newValue
    // }
  },
  beforeDestroy(){
    // window.removeEventListener("onload",this.initWebsocket());
  },
  mounted () {
    this.initWebsocket();
    this.getRoom(this.room_loc);
    this.initRoom();
    // window.addEventListener("onload",this.initWebsocket());
  },
  methods: {
    room_defaultClass:function(){
      console.log('css')
    },
    getRoom:function(room_loc){
      // 更新index
      this.room_loc=room_loc
      console.log('获取房间')
      axios.get(this.baseUrl).then(res=>{
        console.log('返回',res)
      }).catch(error=>{
        console.log('error',error)
      })
    },
    initRoom: function () {
      // 用户信息
// 日期格式化
Date.prototype.Format = function (fmt) {
    var o = {
        "M+": this.getMonth() + 1, //月份 
        "d+": this.getDate(), //日 
        "H+": this.getHours(), //小时 
        "m+": this.getMinutes(), //分 
        "s+": this.getSeconds(), //秒 
        "q+": Math.floor((this.getMonth() + 3) / 3), //季度 
        "S": this.getMilliseconds() //毫秒 
    };
    if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
    for (var k in o)
    if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
    return fmt;
}

      this.room_select = this.room_name[0]
    },
    changeRoom: function (roomName,roomLoc) {
      this.room_loc=roomLoc
      this.room_select=roomName
      // 新建连接
      // this.initWebsocket(roomName)
      console.log('选择房间',roomName)
      // console.log(that)
    },
    initWebsocket: function (roomName) {
      // 默认第一个房间
      let room=roomName!=undefined? roomName:this.room_name[0]
      // 判断房间是否存在,不存在则创建房间
      let chatRoomIndex=0
      try{
        //判断房间是否存在
        let roomFlag=false
        this.chat_info.map((o,index)=>{
          if(o.room==roomName){
            // 房间存在
            console.log('房间存在',roomName)
            roomFlag=true
            chatRoomIndex=index
          }
        })
        if(!roomFlag){
          // 房间不存在,创建
          
          let roomObject={"room":room,"content":[]}
          this.chat_info.push(roomObject)
          console.log("创建房间",this.chat_info)
        }
      }catch(e){
        console.log('创建房间出错',e)
      }
      let wsurl = this.websocketUrl
      
      this.websocket = new WebSocket('ws://' + wsurl + room + '/')// 连接
      console.log(this.websocket,'聊天室')
      this.websocket.onmessage = this.websocketMessage// 函数指向
      this.websocket.onopen = this.websocketOpen
      this.websocket.onerror = this.websocketError
      this.websocket.onclose = this.websocketClose
      // 保存数据 临时容器  房间号
      this.websocket.chat_info= JSON.parse(JSON.stringify(this.chat_info))
      this.websocket.chatRoomIndex= chatRoomIndex
      console.log('实例websocket',this.websocket)
    },
    websocketMessage: function (e) {

      console.log('聊天信息', JSON.parse(JSON.stringify(e.data)))
      let res = JSON.parse(e.data)
      if(res.message.isTrusted){
        console.log('accsee right!')
      }
      else{
          try{
                let dom=document.getElementById('idChat')
                console.log('滚动前',dom.scrollTop,dom.scrollHeight)
                dom.scrollTop=parseInt(dom.scrollHeight)+827
                console.log('滚动后',dom.scrollTop,dom.scrollHeight)
                dom.scrollTop=dom.scrollHeight
      // document.getElementById('idChat').scrollTop+=20
              }
          catch(e){
                console.log(e)
              }

        let message = {"user":this.user,"message":res.message,"create_time":new Date().Format("yyyy-MM-dd HH:mm:ss")}
        // 添加信息
        this.websocket.chat_info[this.websocket.chatRoomIndex].content.push(message)
        // 交换数据
        this.chat_info=this.websocket.chat_info
        console.log('信息',this.chat_info)
      }
    },
    websocketOpen: function (info) {
      this.websocketSend(info)
      this.send_info=''//清空
    },
    websocketSend: function (data) {
      let info = JSON.stringify({
        'message': data
      })
      this.websocket.send(info)
    },
    websocketError: function () {
      this.initWebsocket()// 重连
    },
    websocketClose: function (e) {
      console.log('离开', e)
    }
  },
  destroyed () {
    this.websocketClose()// 关闭
  }
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
24天前
|
前端开发 JavaScript API
(前端3D模型开发)网页三维CAD中加载和保存STEP模型
本文介绍了如何使用`mxcad3d`库在网页上实现STEP格式三维模型的导入与导出。首先,通过官方教程搭建基本项目环境,了解核心对象如MxCAD3DObject、Mx3dDbDocument等的使用方法。接着,编写了加载和保存STEP模型的具体代码,包括HTML界面设计和TypeScript逻辑实现。最后,通过运行项目验证功能,展示了从模型加载到保存的全过程。此外,`mxcad3d`还支持多种其他格式的三维模型文件操作。
|
2月前
|
缓存 前端开发 JavaScript
前端开发的必修课:如何让你的网页在弱网环境下依然流畅运行?
【10月更文挑战第30天】随着移动互联网的普及,弱网环境下的网页性能优化变得尤为重要。本文详细介绍了如何通过了解网络状况、优化资源加载、减少HTTP请求、调整弱网参数和代码优化等方法,提升网页在弱网环境下的加载速度和流畅性,从而改善用户体验。
147 4
|
2月前
|
XML 前端开发 JavaScript
前端大神揭秘:如何让你的网页秒变炫酷,让用户欲罢不能的5大绝招!
前端开发不仅是技术活,更是艺术创作。本文揭秘五大前端开发技巧,包括合理运用CSS动画、SVG图形、现代JavaScript框架、优化网页性能及注重细节设计,助你打造炫酷网页,提升用户体验。
84 30
|
2月前
|
缓存 JavaScript 前端开发
JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用
本文深入讲解了 JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用。
55 5
|
2月前
|
存储 编解码 前端开发
惊!前端新手也能秒懂的高级技巧,轻松提升网页颜值与性能!
本文针对前端新手,介绍了三个简单易学的高级技巧,帮助提升网页的颜值和性能。包括使用CSS框架快速美化网页、优化图片资源加快加载速度,以及利用ARIA属性和媒体查询提高网页的可访问性和响应性。示例代码清晰,适合初学者上手实践。
43 3
|
2月前
|
存储 前端开发 搜索推荐
(前端直接编辑CAD)网页CAD二次开发中线型表的使用方法
在DWG数据库中,线型样式存储在线型样式表 `McDbLinetypeTable` 中,每个线型表记录对象 `McDbLinetypeTableRecord` 对应一种线型样式。本文介绍了如何获取、添加、遍历、删除和修改线型样式,并提供了绘制不同线型的示例代码,包括虚线、点划线和带文字的线型。通过在线示例demo,用户可以实践修改CAD图纸中的实体线型及其样式。
|
2月前
|
搜索推荐 前端开发 开发者
前端开发的必修课:如何让你的网页在搜索引擎中脱颖而出?
【10月更文挑战第31天】前端开发不仅是构建网页与用户间桥梁的关键,还需注重搜索引擎优化(SEO)。优化网页结构、合理使用关键词、提升加载速度及整合社交媒体等技巧,能帮助网页在搜索引擎中脱颖而出,吸引更多用户。
40 5
|
2月前
|
机器学习/深度学习 前端开发 JavaScript
前端小白也能学会的高大上技巧:如何让你的网页支持语音控制?
【10月更文挑战第31天】你是否曾梦想过只需动动嘴皮子就能操控网页?现在,这个梦想触手可及。即使你是前端小白,也能轻松学会让网页支持语音控制的高大上技巧。本文将介绍语音控制的基本概念、实现方法和具体示例,带你走进语音控制的奇妙世界。通过Web Speech API,你只需掌握基本的HTML、CSS和JavaScript知识,就能实现语音识别和控制功能。快来尝试吧!
224 4
|
2月前
|
JSON 前端开发 搜索推荐
惊!这些前端技术竟然能让你的网站实现个性化推荐功能!
【10月更文挑战第30天】随着互联网技术的发展,个性化推荐已成为提升用户体验的重要手段。前端技术如JavaScript通过捕获用户行为数据、实时更新推荐结果等方式,在实现个性化推荐中扮演关键角色。本文将深入解析这些技术,并通过示例代码展示其实际应用。
92 4
|
2月前
|
前端开发 JavaScript 搜索推荐
前端小白也能学会的高大上技巧:如何让你的网页支持暗黑模式?
【10月更文挑战第30天】随着现代网页设计的发展,暗黑模式已成为一种流行趋势,提升了用户的阅读体验并增强了网页的适应性。本文介绍了如何通过简单的HTML、CSS和JavaScript实现网页的暗黑模式。首先,定义两种主题的CSS样式;然后,使用JavaScript实现模式切换逻辑,并自动检测系统主题。通过这些步骤,前端小白也能轻松掌握暗黑模式的实现,提升网页的用户体验和个性化水平。
107 4