使用django+websocket+redis+channels实现简易聊天室

使用django+websocket+redis+channels实现简易聊天室

1.创建一个django项目

从存储项目的文件夹进入cmd命令行终端,输入以下命令创建chatroom项目

django-admin startproject chatroom

然后再进入项目文件夹,打开cmd命令行终端,输入以下命令创建chat应用

python manage.py startapp chat

2.安装所需模块

channels的功能必须依赖于redis数据库,除了安装channels之外,还需安装channels_redis模块,我们使用pip指令分别安装channels和channels_redis,指令如下:

pip install channels
pip install channels_redis
#channels的功能依赖模块
pip install pypiwin32

3.在django中配置channels

(1)在项目应用chat里新建urls.py文件

(2)在chatroom文件夹里创建文件consumers.py和routing.py,文件名可以自行命名

(3)在项目应用chat里新建templates文件夹,在templates文件夹里创建模板文件chat.html和room.html,项目结构如下:

vZ0mUe.png

(4)执行整个项目的数据迁移,因为channels需要使用django内置的会话session机制,用于区分和识别每个用户的身份信息

(5)在django的settings.py里将第三方功能应用channels和chat添加到chatroom,配置如下:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'channels',
    'chat'
]

(6)由于channels的功能依赖与redis数据库,因此还需在settings.py里设置channels的功能设置,配置信息如下:

ASGI_APPLICATION = 'chatroom.routing.application'
CHANNEL_LAYERS={
    'default':{
        'BACKEND':'channels_redis.core.RedisChannelLayer',
        'CONFIG':{
            "hosts":[('127.0.0.1',6379)],
        },
    },
}

(7)功能配置CHANNEL_LAYERS用于设置redis数据库的连接方式,ASGI_APPLICATION指向chatroom的routing.py定义的application对象,该对象把django与channels建立连接,打开chatrooom的routing.py添加如下内容:

from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter
from channels.routing import URLRouter
from .urls import websocket_urlpatterns
application = ProtocolTypeRouter({
    'websocket':AuthMiddlewareStack(
        URLRouter(
            websocket_urlpatterns
        )
    ),
})

(8)在chatroom的urls.py中定义路由对象urlpatterns和websocket_urlpatterns,代码如下:

from django.urls import path,include
from .consumers import ChatConsumer

urlpatterns = [
    path("",include(("chat.urls","chat"),namespace="chat"))
]

websocket_urlpatterns=[
    #使用同步方式实现
    #path('ws/chat/<room_name>/',ChatConsumer),
    #如果使用异步方式实现,路由的视图必须调用as_asgi()
    path('ws/chat/<room_name>/',ChatConsumer.as_asgi()),
]

(9)在chatroom的consumers.py中定义视图类ChatConsumer,代码如下:

from channels.generic.websocket import AsyncWebsocketConsumer
import json

class ChatConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        print("一个客户端连接了服务器")
        self.room_name=self.scope['url_route']['kwargs']['room_name']
        self.room_group_name='chat_%s' % self.room_name
        #join room group
        await self.channel_layer.group_add(
            self.room_group_name,
            self.channel_name
        )
        await  self.accept()

    async def disconnect(self, code):
        # leave room group
        await self.channel_layer.group_discard(
            self.room_group_name,
            self.channel_name
        )
        print("一个客户端断开了连接")

    # receive message from websocket
    async def receive(self, text_data=None, bytes_data=None):
        text_data_json=json.loads(text_data)
        message=text_data_json["message"]
        # send message to room group
        await self.channel_layer.group_send(
            self.room_group_name,
            {
                'type':'chat_message',
                'message':message
            }
        )

    # 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
        }))

4.web在线聊天功能

(1)在项目应用chat的urls.py中分别定义路由newChat和room,代码如下:

from django.urls import path
from .views import *

urlpatterns = [
    #用于开启新的聊天室
    path('',newChat,name="newChat"),
    #创建聊天室
    path('<room_name>/',room,name="room")
]

(2)在chat的views.py中定义视图,代码如下:

from django.shortcuts import render


#用于创建或进入聊天室
def newChat(request):
    return render(request,'chat.html',locals())

#创建聊天室
def room(request,room_name):
    return render(request,'room.html',locals())

(3)编写chat.html模板文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div>请输入聊天室名称</div>
<br/>
<input id="input" type="text" size="30" />
<br/>
<input id="submit" type="button" value="进入">

<script>
    document.querySelector('#input').focus();
    document.querySelector('#input').onkeyup=function (e){
        if (e.keyCode===13){
            document.querySelector('#submit').click();
        }
    };
    document.querySelector('#submit').onclick=function (e){
        var roomName=document.querySelector('#input').value;
        window.location.pathname='/'+roomName + '/';
    }
</script>
</body>
</html>

(4)编写room.html模板文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>聊天室{{ room_name }}</title>
</head>
<body>
<textarea id="chat_log" cols="50" rows="6"></textarea>
<br/>
<input id="input" type="text" size="50"/><br/>
<input id="submit" type="button" value="发送"/>
<script>
    var roomName='{{ room_name }}';
    var chatSocket=new WebSocket(
        'ws://' + window.location.host+'/ws/chat/' + roomName +'/'
    );

    {#将chat发送的数据显示在多行文本输入框中#}
    chatSocket.onmessage=function (e){
        var data=JSON.parse(e.data);
        var message=data['message'];
        document.querySelector('#chat_log').value+=(message +'n');
    };

    {#关闭网页与chat的Channels连接#}
    chatSocket.onclose=function (e){
        console.error('Chat socket closed unexpectedly');
    };

    document.querySelector('#input').focus();
    document.querySelector('#input').onkeyup=function (e){
        if (e.keyCode===13){
            document.querySelector('#submit').click();
        }
    };

    {#网页向chat的channels发送数据#}
    document.querySelector('#submit').onclick=function (e){
        var messageInputDom = document.querySelector('#input');
        var message=messageInputDom.value;
        chatSocket.send(JSON.stringify({
            'message':message
        }));
        messageInputDom.value='';
    }

</script>
</body>
</html>

5.测试聊天室功能

运行项目,打开谷歌浏览器并访问127.0.0.1:8000,在文本输入框输入聊天室名称,并单击进入,如下图所示:

vZ0VHO.png

当成功创建聊天室room0001后,打开另一个浏览器访问127.0.0.1:8000/room0001,聊天室已有两位用户在线,然后使用谷歌浏览器发送消息,发现在另一浏览器可以实时看到消息内容,如下图所示:

vZ0eED.png

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:使用django+websocket+redis+channels实现简易聊天室 - Python技术站

(0)
上一篇 2023年4月2日
下一篇 2023年4月2日

相关文章

  • Django中封装分页组件

    Django中封装分页组件 (1) 定义Paginator类 from django.utils.safestring import mark_safe class Paginator(object): “”” 初始化参数说明: request:请求对象 data:查询到的符合条件的数据 search_data:搜索框收索的关键字,解决收索情况下分页的BUG…

    Python开发 2023年4月2日
    00
  • Django-rest-framework开发api接口

    django-rest-framework开发api接口 (1) 创建django项目drfdemo1并且创建一个名为app的应用 django-admin startproject drfdemo1 python manage.py startapp app (2) 安装django-rest-framework pip install djangores…

    Python开发 2023年4月2日
    00
  • django原生api接口

    django原生api接口 1.1 创建django项目 django-admin startproject drfdemo1 1.2 创建app django-admin startapp app 1.3 创建数据模型 app/models.py中编写如下代码: from django.db import models class studentsInfo…

    2023年4月2日
    00
  • 树结构

    树结构 1.1 树的定义 树(Tree):个节点构成的有限集合。当n = 0时,称为空树。对于任一棵非空树(n>0),它具备以下性质: 树中有一个称为”根(Root)”的特殊节点,用r表示;其余节点可分为m(m>0)个互不相交的有限集、,…,,其中每个集合本身又是一棵树,称为原来树的子树(SubTree)。如下图: 1.2 树结构的术语 树结…

    Python开发 2023年4月2日
    00
  • 自定义Admin后台的登录页面

    自定义Admin后台的登录页面 (1) 在主应用里创建myadmin.py和myapps.py文件,在myadmin.py文件中定义MyAdminSite类,该类继承父类AdminSite并重写admin_view()和get_urls()方法从而更改Admin后台系统地登录地址。 from django.contrib import admin from …

    Python开发 2023年4月2日
    00
  • django中资源文件夹的引入

    django中资源文件夹的引入 1.静态资源文件夹的引入 settings.py的配置如下所示: # django默认配置 STATIC_URL=’static/’ # django会去应用里面的static文件夹找静态资源,仅当DEBUG为True时 # BASE_DIR是项目的绝对地址 STATIC_ROOT=BASE_DIR / ‘static’ # …

    Python开发 2023年4月2日
    00
  • 使用python爬取微博评论

    最近在复习以前学习的python爬虫内容,就拿微博来练了一下手,这个案例适合学习爬虫到中后期的小伙伴,因为他不是特别简单也不是很难,关键是思路,为什么说不是很难呢?因为还没涉及到js逆向,好了话不多说开干。 (1)找到要爬取的页面,如下: (2)点开评论,拉到最下方,如下位置: 点击“点击查看”进入另一个页面,如下所示: 这里会显示更多评论,但是不是全部,随…

    2023年4月2日
    00
合作推广
合作推广
分享本页
返回顶部