在線聊天室是當今互聯網上非常常見的產品。 我們都可以在各個電子商務公司的網絡客服中進行在線聊天。 還有一個培訓機構。 你一打開它的網頁,立刻就會彈出一個在線聊天框,而且很難察覺。
今天周老師給大家帶來了一個后端+前端Vue的小項目教程。
本教程分為三個部分,包括:
非常適合學完之后不會開始寫項目的朋友。
本文為第一篇。 我們將采用傳統的開發模式,借助視圖和模板來完成一個在線聊天室應用程序的開發。
最終效果如下:
我們開始做吧!
創建虛擬環境
為了不與電腦上已有的模塊沖突,我們新建一個虛擬環境:
python -m venv django3_env
復制
進入虛擬環境并激活。
安裝依賴庫
我們使用的后端是框架(在撰寫本文時,最新版本是 3.2,因此我們不需要指定其版本):
pip install django
復制
還有一個重要的依賴庫——.
封裝的原生異步視圖支持讓項目不僅可以處理HTTP,還可以處理需要長期連接的協議,例如:、MQTT、聊天機器人、業余無線電等。
簡而言之,它提供了異步和非HTTP處理的能力。
pip install channels
復制
由于其中一項功能需要使用Redis作為數據通道和緩存,所以我們必須安裝Redis及其相關包。
而Redis在網上并沒有官方支持,所以這里周老師使用Redis替代品來使用Redis:
安裝完成后,它將作為服務在后臺啟動。
然后安裝Redis支持庫:
pip install channels_redis
復制
創建項目
安裝完所有依賴之后,我們開始創建項目:
django-admin startproject chat_backend
復制
然后進入目錄并創建應用程序:
python manage.py startapp chat
復制
配置項
然后我們進行必要的配置,下面的操作都是在.py文件中進行的。
將聊天應用程序添加到項目的應用程序列表中:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'channels',
'chat',
]
復制
在項目根目錄下新建一個文件夾,命名為HTML模板路徑:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
base_DIR / 'templates'
],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
復制
然后指定asgi應用程序:
ASGI_APPLICATION = "chat_backend.asgi.application"
復制
最后,指定要使用的數據通道后端,這里我們使用Redis:
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
"hosts": [('127.0.0.1', 6379)],
},
},
}
復制
主機地址和端口號填寫Redis啟動后顯示的默認值。
創建視圖
在這個“在線聊天室”中,有兩個頁面。 一是主頁,用于輸入房間號和用戶名; 另一個是聊天室頁面,用于聊天。
我們在聊天應用程序的views.py下創建兩個新的視圖函數:
# 首頁
def index(request):
return render(request,'index.html',locals())
# 聊天室
def room(request,room_name):
room_name = room_name
username = request.GET.get('username', '游客')
return render(request,'room.html',locals())
復制
其中,視圖函數index()返回index.html,視圖函數room()返回room.html。 需要在文件夾中創建這兩個 HTML 文件。
定義路線
創建視圖函數后,我們將其綁定到路由上,在聊天應用程序下創建一個名為 urls.py 的新文件,并在其中寫入以下內容:
from django.urls import path
from chat.views import *
# HTTP URL
urlpatterns = [
path('',index,name="index"),
path('/',room,name="room")
]
復制
然后導入該文件夾下的urls.py文件中聊天應用的url配置:
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('chat.urls')),
]
復制
至此,“在線聊天室”項目的HTTP部分已經開發完畢。
訪問首頁,顯示如下圖所示頁面:
我們可以輸入房間號和用戶名進入房間,進入房間后的頁面如下圖所示:
但現在我們還做不到實時聊天,因為實時聊天的核心部分——后端,我們還沒有寫。
寫后端
它是一種長連接的雙向通信協議。 通過它,我們可以在客戶端和服務器之間建立實時通信,而不是HTTP,服務器只有在客戶端發起時才會響應。
在這里,我們使用 中的實現。
首先,在聊天應用程序下新建一個名為.py的文件(意思是,這是<em>中</em>中的一個重要概念),其中我們引入類:
from channels.generic.websocket import AsyncWebsocketConsumer
復制
然后繼承這個類,新建一個名為 的類,并在其中重寫連接、關閉連接、消息接收等方法,代碼如下:
class ChatConsumer(AsyncWebsocketConsumer):
# 連接
async def connect(self):
self.room_name = self.scope['url_route']['kwargs']['room_name']
self.room_group_name = 'chat_%s' % self.room_name
# 加入聊天室
await self.channel_layer.group_add(
self.room_group_name,
self.channel_name
)
await self.accept()
# 關閉連接
async def disconnect(self, close_code):
await self.channel_layer.group_discard(
self.room_group_name,
self.channel_name
)
#
async def receive(self, text_data=None, bytes_data=None):
data = json.loads(text_data)
message = data['message']
username = data['username']
# Send message to room group
await self.channel_layer.group_send(
self.room_group_name,
{
'type': 'chat_message',
'message': message,
'username': username
}
)
# 接收消息
async def chat_message(self, event):
message = event['message']
username = event['username']
# 發送消息到 Websocket
await self.send(text_data=json.dumps({
'message': message,
'username': username
}))
復制
最后,我們在 asgi 中重新聲明路由。 打開目錄下的asgi.py文件,修改內容如下:
import os
from django.core.asgi import get_asgi_application
from django.urls import path
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from chat.consumers import ChatConsumer
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'chat_backend.settings')
application = ProtocolTypeRouter({
"http": get_asgi_application(),
"websocket": AuthMiddlewareStack(
URLRouter([
path("ws//",ChatConsumer.as_asgi()),
])
)
})
復制
如上面的代碼所示,HTTP是通過傳統的HTTP路由處理的,而HTTP是通過. 這樣我們的項目啟動后就可以同時支持HTTP訪問和訪問了。
前連接
后端提供服務,前端需要連接和處理。
我們看一下前端的處理。
首先,通過創建對象來創建連接:
// 建立一個 websocket 連接
const chatSocket = new WebSocket(
'ws://' + window.location.host + '/ws/' + roomName + '/'
);
復制
然后編寫各種事件的回調函數:
// websocket連接關閉后的回調函數
chatSocket.onclose = function(e) {
console.error('The socket closed unexpectedly');
};
// websocket連接從服務器收到消息的回調函數
chatSocket.onmessage = function(e) {
const data = JSON.parse(e.data);
if (data.message) {
if(data.username == userName){
document.querySelector('#chat-record').innerHTML += ('' + data.username + '' + data.message + '
');
}else{
document.querySelector('#chat-record').innerHTML += ('' + data.username + '' + data.message + '
');
}
} else {
alert('消息為空!')
}
};
復制
這樣前端就完成了對后端的連接和消息接收。
終于
項目運行后,我們可以在網頁上實時聊天。
當然,這個項目還存在很多問題,比如:
接下來,讓我們繼續完善這個“在線聊天室”,敬請期待!
分享、點贊、觀看,讓我看到你們的熱情!