django實現聊天室、消息推送

  • Django-channel可以做什麼

在Django中,默認使用的是HTTP通信,不過這種通信方式有個很大的缺陷,就是不能很好的支持實時通信。如果硬是要使用HTTP做實時通信的話只能在客戶端進行輪詢了,不過這樣做的開銷太大了。

因此,在1.9版本之後,Django實現了對Channels的支持,他所使用的是WebSocket通信,解決了實時通信的問題,而且在使用WebSocket進行通信的同時依舊能夠支持HTTP通信。

  • 實現結果

本項目實現了聊天室、消息推送。

  • 項目配置

  1. 搭建Django項目

不在講述搭建項目步驟,以下是項目結構。

 

  1. 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"],
        },
    },
}
  1. 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請求將有此類方法進行處理。

  1. 瀏覽器

瀏覽器發起websocket的請求,創建websocket對象支持四個消息:

onopen: 當瀏覽器和websocket服務端連接成功後會觸發onopen消息。

onerror: 如果連接失敗,或者發送、接收數據失敗,或者數據處理出錯都會觸發onerror消息。

onmessage: 當瀏覽器接收到websocket服務器發送過來的數據時,就會觸發onmessage消息,參數e包含了服務端發送過來的數據。

onclose: 當瀏覽器接收到websocket服務器發送過來的關閉連接請求時,會觸發onclose消息。

  1. 服務器

創建一個房間名爲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函數去處理。

  • 知識點拓展

目前想到可以拓展的方向,

  1. 在發送消息通告時判斷當前連接人數(即此時登錄我們後臺網站)。
  2. 爲指定用戶推送消息。
  3. 優化輪詢,實時顯示處理進度,減少資源。

 

代碼地址:https://github.com/AIlvxiaobu/django_websocket.git

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章