在線聊天室是當今互聯(lián)網(wǎng)上常見的產(chǎn)品,在各種電商的網(wǎng)絡(luò)客戶服務(wù)中,我們都能接觸到在線聊天。
還有一個培訓(xùn)機構(gòu),你一打開他的網(wǎng)頁,立馬就彈出一個在線聊天框,防不勝防。這個教程分為上中下三篇,其中:
- 上篇使用 Django 傳統(tǒng)的 MTV 模式進行開發(fā),實現(xiàn)一個在線聊天室的功能。
- 中篇在上篇基礎(chǔ)上加入數(shù)據(jù)存儲,實現(xiàn)聊天記錄的保存。
- 下篇則采用后端 Django + 前端 Vue 對傳統(tǒng)的 Web 模開發(fā)式進行改造。
非常適合學(xué)了 Django 之后寫項目無從下手的朋友們。
本篇為上篇,我們將使用 Django 的傳統(tǒng)開發(fā)模式,借助視圖和模板完成一個在線聊天室應(yīng)用的開發(fā)。
最終效果如下所示:
直接開干吧!
創(chuàng)建虛擬環(huán)境
為了不與計算機上現(xiàn)有的 Python 模塊沖突,我們新起一個 Python 虛擬環(huán)境:
python -m venv django3_env
進入虛擬環(huán)境,然后激活它。
安裝依賴庫
后端我們使用的是 Django3 框架(在本文編寫時,Django 的最新版本為 3.2,所以我們不需要指定它的版本):
pip install django
還有一個重要的依賴庫——Channels。
Channels 封裝了 Django 的原生異步視圖支持,讓 Django 項目不僅可以處理 HTTP,還可以處理需要長時間連接的協(xié)議,比如:WebSockets、MQTT、聊天機器人、業(yè)余無線電等等。
簡而言之,就是為 Django 提供了異步和非 HTTP 處理的能力。
pip install channels
因為 Channels 中的一個功能需要使用到 Redis 作為數(shù)據(jù)通道和緩存,所以我們得安裝 Redis 以及其 Python 相關(guān)的包。
而 Redis 在 Windows 上沒有官方的支持,所以在這里,使用一個 Redis 的替代品 Memurai 來當 Redis 使用:
安裝完成后即會作為 Windows 的服務(wù)在后臺啟動。
然后安裝 Channels 的 Redis 配套庫:
pip install channels_redis
創(chuàng)建項目
安裝好所有的依賴項之后,我們開始創(chuàng)建 Django 項目:
django-admin startproject chat_backend
然后進入 chat_backend 目錄,創(chuàng)建一個應(yīng)用:
python manage.py startapp chat
配置項目
接著我們進行必要的配置,下述操作在 文件中進行。
添加 channels、chat 應(yīng)用到 Django 項目的應(yīng)用列表:
INSTALLED_APPS = [ 'django.con;, 'django.con;, 'django.con;, 'django.con;, 'django.con;, 'django.con;, 'channels', 'chat', ]
在項目根目錄下新建名為templates的文件夾,然后定義 HTML 模板路徑:
TEMPLATES = [ { 'BACKEND': 'django.;, 'DIRS': [ BASE_DIR / 'templates' ], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.;, 'django.;, 'django.con;, 'django.con;, ], }, }, ]
然后指定 asgi 應(yīng)用:
ASGI_APPLICATION = "c;
最后,指定 Channels 使用的數(shù)據(jù)通道后端,在這里我們使用的是 Redis:
CHANNEL_LAYERS = { 'default': { 'BACKEND': 'c;, 'CONFIG': { "hosts": [('127.0.0.1', 6379)], }, }, }
其中主機地址和端口號填寫 Redis 啟動后顯示的默認值。
創(chuàng)建視圖
在這個「在線聊天室」里面,一共有兩個頁面。一個是首頁,用于輸入房間號和用戶名;另一個則是聊天房間的頁面,用于進行聊天。
我們在 chat 應(yīng)用的 views.py 下新建兩個視圖函數(shù):
# 首頁 def index(request): return render(request,'index.html',locals()) # 聊天室 def room(request,room_name): room_name = room_name username = reque('username', '游客') return render(request,'room.html',locals())
其中,視圖函數(shù)index()返回 index.html,視圖函數(shù)room()返回 room.html,這兩個 HTML 文件需要我們在templates文件夾中進行創(chuàng)建。
定義路由
視圖函數(shù)創(chuàng)建好之后,我們?yōu)槠浣壎酚?,?chat 應(yīng)用下新建一個名為urls.py的文件,在其中寫入如下內(nèi)容:
from django.urls import path from c import * # HTTP URL urlpatterns = [ path('',index,name="index"), path('<str:room_name>/',room,name="room") ]
然后在 chat_backend 文件夾下的 urls.py 文件內(nèi)引入 chat 應(yīng)用的 url 配置:
urlpatterns = [ path('admin/', admin.), path('', include('c;)), ]
至此,「在線聊天室」這個項目的 HTTP 部分已經(jīng)完成了開發(fā)。
訪問首頁,會顯示如下圖所示的頁面:
我們可以輸入房間號和用戶名進入房間,進入房間后的頁面如下圖所示:
但是現(xiàn)在我們還不能進行在線聊天,因為在線聊天最核心的部分——WebSocket后端,我們還沒有編寫。
編寫 WebSocket 后端
WebSocket 是一個長連接的雙向通信協(xié)議。通過 WebSocket 我們可以在客戶端和服務(wù)器端之間建立實時的通信,而不是像 HTTP 那樣,只有客戶端發(fā)起,服務(wù)器端才會響應(yīng)。
在這里,我們借助 Channels 在 Django 中實現(xiàn) WebSocket。
首先,在 chat 應(yīng)用下新建一個名為con的文件(意為消費者,是 Channels 中的一個重要概念),在其中,我們引入 WebSocket 類:
from c import AsyncWebsocketConsumer
然后繼承這個類,新建一個名為ChatConsumer的類,并在其中重寫 WebSocket 的連接、關(guān)閉連接、消息接收等方法,代碼如下所示:
class ChatConsumer(AsyncWebsocketConsumer): # 連接 async def connect(self): = ['url_route']['kwargs']['room_name'] = 'chat_%s' % # 加入聊天室 await ( , ) await () # 關(guān)閉連接 async def disconnect(self, close_code): await ( , ) # async def receive(self, text_data=None, bytes_data=None): data = j(text_data) message = data['message'] username = data['username'] # Send message to room group await ( , { 'type': 'chat_message', 'message': message, 'username': username } ) # 接收消息 async def chat_message(self, event): message = event['message'] username = event['username'] # 發(fā)送消息到 Websocket await (text_data=j({ 'message': message, 'username': username }))
最后,我們在 asgi 中重新聲明路由。打開 chat_backend 目錄下的 a 文件,將內(nèi)容修改為如下所示:
import os from django.core.asgi import get_asgi_application from django.urls import path from c import AuthMiddlewareStack from c import ProtocolTypeRouter, URLRouter from c import ChatConsumer os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'c;) application = ProtocolTypeRouter({ "http": get_asgi_application(), "websocket": AuthMiddlewareStack( URLRouter([ path("ws/<str:room_name>/",C()), ]) ) })
如上代碼所示,HTTP 通過 get_asgi_application 以傳統(tǒng)的 HTTP 路由進行處理,而 WebSocket 則通過 Channels 的 URLRouter 進行處理。這樣我們的項目啟動之后就可以同時支持 HTTP 訪問和 WebSocket 訪問。
前端連接 WebSocket
后端提供了 WebSocket 服務(wù),前端需要進行連接和處理才行。
來看看前端的處理過程。
首先,通過 new 一個 WebSocket對象,來創(chuàng)建 WebSocket連接:
// 建立一個 websocket 連接 const chatSocket = new WebSocket( 'ws://' + window.loca + '/ws/' + roomName + '/' );
然后編寫 WebSocket 各類事件的回調(diào)函數(shù):
// websocket連接關(guān)閉后的回調(diào)函數(shù) c = function(e) { con('The socket closed unexpectedly'); }; // websocket連接從服務(wù)器收到消息的回調(diào)函數(shù) c = function(e) { const data = JSON.parse); if ) { i == userName){ document.querySelector('#chat-record').innerHTML += ('<div class="right_msg">' + da + '<div class="right-record"><span>' + da + '</span></div></div><br>'); }else{ document.querySelector('#chat-record').innerHTML += ('<div class="left_msg">' + da + '<div class="left-record"><span>' + da + '</span></div></div><br>'); } } else { alert('消息為空!') } };
這樣前端就完成了對后端 WebSocket 的連接和消息接收。
最后
運行項目,我們就可以在網(wǎng)頁上進行實時在線聊天了。
當然,現(xiàn)在這個項目還有很多問題,比如:
- 聊天記錄不會保存,刷新頁面之后聊天記錄就會消失。
- 沒有用戶認證和鑒權(quán),誰都能輸入房間號和用戶名進入聊天室。
接下來,讓我們繼續(xù)完善這個「在線聊天室」,敬請期待!
1.《關(guān)于聊天室怎么進我想說使用 Python 開發(fā)一個在線聊天室》援引自互聯(lián)網(wǎng),旨在傳遞更多網(wǎng)絡(luò)信息知識,僅代表作者本人觀點,與本網(wǎng)站無關(guān),侵刪請聯(lián)系頁腳下方聯(lián)系方式。
2.《關(guān)于聊天室怎么進我想說使用 Python 開發(fā)一個在線聊天室》僅供讀者參考,本網(wǎng)站未對該內(nèi)容進行證實,對其原創(chuàng)性、真實性、完整性、及時性不作任何保證。
3.文章轉(zhuǎn)載時請保留本站內(nèi)容來源地址,http://f99ss.com/gl/2490992.html