-
Django-channel可以做什麼
在Django中,默認使用的是HTTP通信,不過這種通信方式有個很大的缺陷,就是不能很好的支持實時通信。如果硬是要使用HTTP做實時通信的話只能在客戶端進行輪詢了,不過這樣做的開銷太大了。
因此,在1.9版本之後,Django實現了對Channels的支持,他所使用的是WebSocket通信,解決了實時通信的問題,而且在使用WebSocket進行通信的同時依舊能夠支持HTTP通信。
-
實現結果
本項目實現了聊天室、消息推送。
-
項目配置
-
搭建Django項目
不在講述搭建項目步驟,以下是項目結構。
- Setting配置
INSTALLED_APPS中添加channels;
指定ASGI的路由地址,添加ASGI_APPLICATION = 'tbkt.routing.application'
設置消息通道,添加CHANNEL_LAYERS配置
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
"hosts": ["redis://:password@address:port/db"],
},
},
}
-
Routing——websocket路由配置(類似於Django中的urls系統)
在setting同級目錄下創建routing.py文件,文件內容如下:
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
import apps.routing
application = ProtocolTypeRouter({
'websocket': AuthMiddlewareStack(
URLRouter(
apps.routing.websocket_urlpatterns
)
),
})
ProtocolTypeRouter: ASIG支持多種不同的協議,在這裏可以指定特定協議的路由信息,我們只使用了websocket協議,這裏只配置websocket即可。
AuthMiddlewareStack: django的channels封裝了django的auth模塊,使用這個配置我們就可以在consumer中通過下邊的代碼獲取到用戶的信息。
具體的路由配置:
from apps.chat.consumers import ChatConsumer
from apps.message.consumers import MsgConsumer
from django.conf.urls import url
websocket_urlpatterns = [
url('ws/chat/', ChatConsumer),
url('ws/message/', MsgConsumer),
]
ChatConsumer 是處理請求的類方法。Websocket請求將有此類方法進行處理。
- 瀏覽器
瀏覽器發起websocket的請求,創建websocket對象支持四個消息:
onopen: 當瀏覽器和websocket服務端連接成功後會觸發onopen消息。
onerror: 如果連接失敗,或者發送、接收數據失敗,或者數據處理出錯都會觸發onerror消息。
onmessage: 當瀏覽器接收到websocket服務器發送過來的數據時,就會觸發onmessage消息,參數e包含了服務端發送過來的數據。
onclose: 當瀏覽器接收到websocket服務器發送過來的關閉連接請求時,會觸發onclose消息。
- 服務器
創建一個房間名爲Group name,所有的消息都會發送到這個Group裏邊,當然你也可以通過參數的方式將房間名傳進來作爲Group name,從而建立多個Group,這樣可以實現僅同房間內的消息互通。
當我們啓用了channel layer之後,所有與consumer之間的通信將會變成異步的,所以必須使用async_to_sync。
一個鏈接(channel)創建時,通過group_add將channel添加到Group中,鏈接關閉通過group_discard將channel從Group中剔除,收到消息時可以調用group_send方法將消息發送到Group,這個Group內所有的channel都可以收的到。
group_send中的type指定了消息處理的函數,這裏會將消息轉給chat_message函數去處理。
-
知識點拓展
目前想到可以拓展的方向,
- 在發送消息通告時判斷當前連接人數(即此時登錄我們後臺網站)。
- 爲指定用戶推送消息。
- 優化輪詢,實時顯示處理進度,減少資源。