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()// 关闭
  }
目录
相关文章
|
4月前
|
JavaScript 前端开发 Java
制造业ERP源码,工厂ERP管理系统,前端框架:Vue,后端框架:SpringBoot
这是一套基于SpringBoot+Vue技术栈开发的ERP企业管理系统,采用Java语言与vscode工具。系统涵盖采购/销售、出入库、生产、品质管理等功能,整合客户与供应商数据,支持在线协同和业务全流程管控。同时提供主数据管理、权限控制、工作流审批、报表自定义及打印、在线报表开发和自定义表单功能,助力企业实现高效自动化管理,并通过UniAPP实现移动端支持,满足多场景应用需求。
419 1
|
9月前
|
前端开发 JavaScript API
(前端3D模型开发)网页三维CAD中加载和保存STEP模型
本文介绍了如何使用`mxcad3d`库在网页上实现STEP格式三维模型的导入与导出。首先,通过官方教程搭建基本项目环境,了解核心对象如MxCAD3DObject、Mx3dDbDocument等的使用方法。接着,编写了加载和保存STEP模型的具体代码,包括HTML界面设计和TypeScript逻辑实现。最后,通过运行项目验证功能,展示了从模型加载到保存的全过程。此外,`mxcad3d`还支持多种其他格式的三维模型文件操作。
740 118
|
5月前
|
人工智能 自然语言处理 前端开发
DeepSite:基于DeepSeek的开源AI前端开发神器,一键生成游戏/网页代码
DeepSite是基于DeepSeek-V3模型的在线开发工具,无需配置环境即可通过自然语言描述快速生成游戏、网页和应用代码,并支持实时预览效果,显著降低开发门槛。
1137 93
DeepSite:基于DeepSeek的开源AI前端开发神器,一键生成游戏/网页代码
|
5月前
|
移动开发 前端开发 JavaScript
Vue与React两大前端框架的主要差异点
以上就是Vue和React的主要差异点,希望对你有所帮助。在选择使用哪一个框架时,需要根据项目的具体需求和团队的技术栈来决定。
338 83
|
6月前
|
JSON 自然语言处理 前端开发
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
280 72
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
|
5月前
|
存储 前端开发 JavaScript
调用DeepSeek API增强版纯前端实现方案,支持文件上传和内容解析功能
本方案基于DeepSeek API增强版,提供纯前端实现的文件上传与内容解析功能。通过HTML和JavaScript,用户可选择文件并调用API完成上传及解析操作。方案支持多种文件格式(如PDF、TXT、DOCX),具备简化架构、提高响应速度和增强安全性等优势。示例代码展示了文件上传、内容解析及结果展示的完整流程,适合快速构建高效Web应用。开发者可根据需求扩展功能,满足多样化场景要求。
1962 64
|
4月前
|
JavaScript 前端开发 编译器
Vue与TypeScript:如何实现更强大的前端开发
Vue.js 以其简洁的语法和灵活的架构在前端开发中广受欢迎,而 TypeScript 作为一种静态类型语言,为 JavaScript 提供了强大的类型系统和编译时检查。将 Vue.js 与 TypeScript 结合使用,不仅可以提升代码的可维护性和可扩展性,还能减少运行时错误,提高开发效率。本文将介绍如何在 Vue.js 项目中使用 TypeScript,并通过一些代码示例展示其强大功能。
198 22
|
6月前
|
人工智能 JavaScript 前端开发
Vue 性能革命:揭秘前端优化的终极技巧;Vue优化技巧,解决Vue项目卡顿问题
Vue在处理少量数据和有限dom的情况下技术已经非常成熟了,但现在随着AI时代的到来,海量数据场景会越来越多,Vue优化技巧也是必备技能。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
10月前
|
JavaScript 前端开发 搜索推荐
Vue的数据驱动视图与其他前端框架的数据驱动方式有何不同?
总的来说,Vue 的数据驱动视图在诸多方面展现出独特的优势,其与其他前端框架的数据驱动方式的不同之处主要体现在绑定方式、性能表现、触发机制、组件化结合、灵活性、语法表达以及与后端数据交互等方面。这些差异使得 Vue 在前端开发领域具有独特的地位和价值。
203 58
|
8月前
|
JavaScript 前端开发 jenkins
抛弃node和vscode,如何用记事本开发出一个完整的vue前端项目
本文探讨了在不依赖Node和VSCode的情况下,仅使用记事本和浏览器开发一个完整的Vue3前端项目的方法。通过CDN引入Vue、Vue Router、Element-UI等库,直接编写HTML文件实现页面功能,展示了前端开发的本质是生成HTML。虽然日常开发离不开现代工具,但掌握这种基础方法有助于快速实现想法或应对特殊环境限制。文章还介绍了如何用Node简单部署HTML文件到服务器,提供了一种高效、轻量的开发思路。
165 10

热门文章

最新文章