Django + WebSocket + Redis 線上聊天室題文章
話不多說先上效果圖演示
專案:http://112.74.164.107:9990/
1、安裝組建
redis: yum install redis/apt install redis
2、建立虛擬化環境並進入
python3/python -m venv venv
source venv\bin\active
3、安裝第三方庫
pip install -r requirements.txt
4、初始化
python manage.py makemigrations
python manage.py migrate
python manage.py collectstatic
5、啟動服務
gunicorn -w 5 -k gevent -b 0.0.0.0:9990 webchat.wsgi
6、訪問
瀏覽器訪問http://ip:9990
整個專案中涉及的思路和知識點我們在這裡都一一分解為大家詳細解說如下:
Django 基礎
Django :一個可以使 Web 開發工作愉快並且高效的 Web 開發框架,能夠以最小的代價構建和維護高質量的 Web 應用
框架:軟體開發工程師從日常的重複勞動中總結出快速的、模組化的、安全的軟體開發模式
Django 是 Python 開發者的最佳 Web 框架
MVC
ORM
Object Relation Mapping (關係物件對映)
- 用來把物件模型表示的物件對映到基於 SQL 的關係模型資料庫結構中去
- 在具體的操作實 體物件的時候,就不 需要再去和複雜的 SQL 語句打交道,只 需簡單的操作實體對 象的屬性和方法
Mail (通過郵箱和驗證碼方式進行使用者登入驗證)
開發者可為使用 Django 提供的 send_mail 函式傳送郵件
使用方法
配置郵箱(setting.py)
- EMAIL_HOST = 'smtp-mail.outlook.com'
- EMAIL_PORT = 587
- EMAIL_HOST_USER = '[email protected]'
- EMAIL_HOST_PASSWORD = ‘xxxxxx'
- EMAIL_USE_TLS = True
- EMAIL_FROM = EMAIL_HOST_USER
傳送
send_mail(subject, message, from_email, recipient_list, fail_silently=False, auth_user=None, auth_password=None, connection=None, html_message=None)
注: django 傳送郵件封裝 python smtplib 模組,smtplib 使用方 法: https://github.com/imsilence/packages/blob/master/python/mailclient.py
Session & Cookie
實現使用者認證機制
- HTTP 協議為無狀態
- Session 儲存在伺服器
- Cookie 儲存在客戶端
WebSocket 基礎(實現服務端訊息主動推送客戶端)
是什麼?
WebSocket 是 HTML5 開始提供的一種在單個 TCP 連線上進行全雙工通訊的協議
為什麼需要?
HTTP 協議是一種無狀態的、無連線的、單向的應用層協議。它採用了請
求/響應模型。通訊請求只能由客戶端發起,服務端對請求做出應答處理
弊端: HTTP 協議無法實現伺服器主動向客戶端發起訊息。
傳統模式下, Web 應用程式通過頻繁的 ajax 請求實現長輪詢( 輪詢是在 特定的時間間隔(如每1秒),由瀏覽器對伺服器發出 HTTP 請求,然後由 伺服器返回最新的資料給客戶端的瀏覽器)
缺點:輪詢的效率低,非常浪費頻寬等資源(瀏覽器需要不斷的向伺服器
發出請求)
如何工作?
Web 瀏覽器和伺服器都必須實現 WebSockets 協議來建立和維護連 接,由於 WebSockets 連線長期存在,與典型的 HTTP 連線不同,對 伺服器有重要的影響(任何 WebSockets 伺服器都需要實現為非同步服 務器,基於多執行緒或多程序的伺服器無法適用於 WebSockets,因為 它旨在開啟連線,儘可能快地處理請求,然後關閉連線)
在 WebSocket 協議中, 瀏覽器和伺服器只需要做一個握手的動作,然後,瀏覽器和伺服器之間就形成了一條快速通道。兩者之間就直接可以資料互相傳送。
如何使用?
客戶端 API (javascript)
1、建立 websocket 物件
var ws = new WebSocket(url, [protocol] );
2、屬性
ws.readyState 表示連線狀態
可選值:
0: 表示連線尚未建立。
1: 表示連線已建立,可以進行通訊。
2: 表示連線正在進行關閉。
3: 表示連線已經關閉或者連線不能開啟。
ws.bufferedAmount 表示已被 send() 方法放入正在佇列中等待傳輸,但是還沒有發 出的 UTF-8 文字位元組數
3、事件
- open ws.onopen 建立連線時觸發
- message ws.onmessage 客戶端接收服務端資料時觸發
- error ws.onerror 通訊發生錯誤時觸發
- close ws.onclose 連線關閉時觸發
4、方法
send ws.send() 使用連線傳送資料
close ws.close() 關閉連線
dwebsocket 使用
dwebsocket 模組為 django 提供了 WebSocket 協議的實現
使用
1、安裝
pip install dwebsocket
2、用法
使用 accept_websocket 或 require_websocket 裝飾器修飾 view
- accept_websocket: view 既可處理 websocket 協議又可處理普通 http協議
- require_websocket: view 只處理 websocket 協議,拒絕處理普通 http協議
request.is_websocket 方法用於判斷是否為 websocket 協議
獲取 websocket 連線物件
- request.websocket 物件
獲取資料
- request.websocket.wait 方法, 阻塞性獲取客戶端資料
- request.websocket.read 方法,非阻塞性獲取客戶端資料
傳送資料
- request.websocket.send(message): 傳送訊息給 websocket 客戶端
其他
- request.websocket.count_messages()
- request.websocket.has_messages()
- request.websocket.iter()
redis 基礎
Redis 是一個開源的,基於記憶體的,可持久化的,K-V 資料庫
用途:
- 快取
- 訊息佇列
- 釋出訂閱
釋出訂閱:是一種訊息通訊模式,傳送者(pub)傳送訊息,縮 影訂閱者(sub)都可以接收訊息並處理
1、在 redis 客戶端中使用
- 訂閱:subscribe channel
- 釋出:publish channel message
2、在 python 中使用
redis 模組
- pip install redis
- cli = redis.StrictRedis()
訂閱
- pubsub = cli.pubsub()
- pubsub.subscribe(channel)
- pubsub.get_message()
釋出:
- cli.publish(channel, message)
程式碼解讀——專案啟動
程式碼結構
app 定義(app.py)
配置(settings.py)
-
配置訪問地址
-
啟用 app
-
配置模版路徑
-
配置時區和國際化
-
配置靜態資源路徑
-
配置郵箱
- 配置 redis 快取
程式碼解讀——使用者認證流程
流程
1、開啟登入頁面
- 瀏覽器中輸入 http://ip:9990/login/, 瀏覽器傳送 GET 請求到 login/
- urls.py 處理 url login/ 到檢視 login
- login 檢視 開啟 login.html 模板
2、傳送驗證碼
- 填寫郵箱,點擊發送驗證碼按鈕,瀏覽器傳送 ajax(GET) 請求到 login_code/
- urls.py 處理 url login_code/ 到檢視 login_code
- login 檢視呼叫 models 建立並記錄驗證碼,同時傳送郵件給使用者,返回 json 數 據
3、登入
- 填寫驗證碼,點選登陸按鈕,瀏覽器傳送 ajax(POST) 請求到 login/
- urls.py 處理 url login/ 到檢視 login
- login 檢視呼叫 models 驗證郵箱和驗證碼,返回 json 資料,當驗證成功同時記錄 session 資料
路由(url.py)
檢視-view.py
檢視-models.py
檢視-templates/login.html
程式碼解讀——websocket 處理流程
流程
建立 websocket 連線到 msg/,同時註冊 open, error, message 事件
當連線建立,呼叫 websocket.send 傳送上線訊息
使用者填寫訊息,點選按鈕,呼叫 websocket.send 方法傳送聊天訊息
urls.py 處理 url msg/ 到檢視 msg
msg 檢視接收和處理 websocket 訊息,同時監聽和處理 redis 訂閱的 訊息
- 當接收到 websocket 訊息,釋出訊息到 redis 通道
- 當接收到 redis 釋出訊息,則傳送到 websocket 客戶端
獲取 websocket 連線和傳送訊息(index.html)
路由處理(view.py)
訊息顯示處理(index.html)
程式碼解讀——推出登陸流程
想要原始碼的請留言或者私信博主