使用django+websocket+redis+channels實現簡易聊天室

来源:https://www.cnblogs.com/minqiliang/archive/2022/08/03/16548465.html
-Advertisement-
Play Games

使用django+websocket+redis+channels實現簡易聊天室 1.創建一個django項目 從存儲項目的文件夾進入cmd命令行終端,輸入以下命令創建chatroom項目 django-admin startproject chatroom 然後再進入項目文件夾,打開cmd命令行終 ...


使用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


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1. 表格標簽 1.1主要作用 顯示和展示數據美觀、良好。 1.2基本語法 <table> <tr> <td>單元格內的文字</td> ... </tr> ... </table> <table></table>用來定義表格的標簽 <tr></tr>標簽用於定義表格中的行,必須鑲嵌在<table>< ...
  • 在設計網頁的時候常常遇到這種情況:一個元素使用的樣式與另一個元素完全相同,但又添加了額外的樣式。 通常會在 HTML 中給元素定義兩個 class,一個通用樣式,一個特殊樣式。 普通CSS的實現 接下來以警告框為例進行講,解4種類型 | 類型 | 說明 | | | | | info | 信息!請註意 ...
  • 如果你有玩過 🎮 《王者榮耀》、《陰陽師》 等手游,一定註意到過它的啟動動畫、皮膚立繪卡片等場景,經常採用靜態底圖加局部液態流動效果的簡單動畫,本文使用前端開發技術,結合 SVG 和 CSS 來實現類似的液化流動效果。本文包含的知識點主要包括:mask-image 遮罩、feTurbulence ... ...
  • 一個工作薄中快速新建多個數據表 一、建立數據源數表 將所有數據統一錄入到本數據源表中,併進行統一排列數據。 註意:這裡的序號很重要,是對應後面工作表格獲取數據的來源,具體見公式設置。 二、建立一個表格模板 ① 將自己需要的表格進行製作及調整格式。 註意:做好表格列印格式調整。 ② 表格做好讀取表格名 ...
  • 1.用戶定義 在前面的案例中,我們的登錄用戶是基於配置文件來配置的(本質是基於記憶體),但是在實際開發中,這種方式肯定是不可取的,在實際項目中,用戶信息肯定要存入資料庫之中。 Spring Security支持多種用戶定義方式,接下來我們就逐個來看一下這些定義方式。通過前面的介紹(參見3小節),大家對 ...
  • 目錄 一.簡介 二.效果演示 三.源碼下載 四.猜你喜歡 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 基礎 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 轉場 零基礎 O ...
  • 1.文件上傳 新建空項目 準備工作 在maven倉庫里下載commons io 和 commons fileupload兩個jar包 實用類介紹 文件上傳註意事項 為保證伺服器安全,上傳文件應該放在外界無法直接訪問的目錄下,比如放在WEB-INF目錄下 為防止文件覆蓋現象發生,要為上傳文件產生一個唯 ...
  • Java概述 什麼是Java? Java 是一種編程語言和計算平臺,由 Sun Microsystems 在 1995 年首次發佈。它從微末起步,逐漸發展為當今數字世界中很大一部分資產所依賴的基礎,是用於構建許多服務和應用程式的可靠平臺。面向未來的創新產品和數字服務也仍然依賴 Java。 儘管大多數 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...