Django channels

      最近完成的一個項目用到了websock+channels實現實時通信,這裏把本身的心得寫下來分享分享,但願能夠對有這方面的需求的朋友有所幫助。html

       channels是django1.9之後纔出的一個新的特性,它容許Django以「通道模式」運行,經過創建通道層,來向消費者和生產者(消息發送者)之間傳遞消息。git

        安裝channels:pip install channelsgithub

        安裝channels所依賴的通道層(通常都是redis,也能夠是別的):pip install asgi_redisweb

        在Django項目中配置channnels:redis

        1.在settings文件的INSTALLED_APPS裏面加入channelsdjango

          INSTALLED_APPS = [
               . . .服務器

                'channels',
          ]websocket

         2.在settings文件中加入channels通道層的配置:異步

CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "asgi_redis.RedisChannelLayer",
        "CONFIG": {
            "hosts":[("localhost", 6379)], 
        },
        "ROUTING": "testchannels.routing.routing",
    },
}socket

      解釋一下這段代碼:它跟DATABASES的配置有點像,BACKEND指定channels通道層由redis實現。CONFIG是IP跟redis端口。ROUTING又叫通道路由,通道路由將通道映射到消費者函數。跟 urls.py相似,當有WebSocket請求訪問時,就會根據這個路徑找到相應表單,調用相應的函數進行處理,按照慣例通道路由應該在routing.py裏。

       3.替換掉Django的基於HTTP/WSGI的請求處理器,而是使用通道。它是一個基於新興標準ASGI(異步服務器網關接口)的, 因此咱們將在asgi.py文件裏定義處理器:

       上面的都配置完之後就能夠開始寫代碼了。

       主要要建立2個文件——consumer.py,routing.py

       routing.py:

      

當websocket創建鏈接時,會尋找websocket.connet,而後調用noGroupConsumer.ws_connect方法。 

當websocket發送數據時,會尋找websocket.receive,而後調用noGroupConsumer.ws_receive方法。

 當websocket斷開鏈接時,會尋找websocket.disconnect,而後調用noGroupConsumer.ws_disconnect方法。

而後建立個人consumer文件noGroupConsumer.py:

     

每行代碼什麼意思都標註清楚了,這裏就不作解釋了。

測試:運行項目,而後建立一個websocket鏈接發送消息。

鏈接websocket而後發送一個「hello world」,這時會彈一個框 hello world說明channels成功。

注意圖上畫紅圈的url跟routing裏面的對照一下。

Group

      上面只是最基本的websocket+channels知識。若是有不少的websocket鏈接,可是他們須要收到不一樣的消息,怎麼處理呢?就好比A集合跟B集合兩個websocket鏈接集合。A集合中的任何一個元素髮了一條信息,全部元素都能收到,可是B集合根本不想收到A集合中元素髮的信息,怎麼辦呢?channels中的Group就是解決這個問題的——把信息發送到它須要的地方。

routing.py:

consumer:groupConsumer.py:

        當創建鏈接後,把鏈接存入到Group中:Group("myRoom").add(message.reply_channel)

myRoom是Group的名字。Group("myRoom").send({"text":data})就會把數據發送到加入到myRoom裏面的鏈接。

咱們能夠改一下上面那個html代碼

跟以前惟一不一樣的就是websocket url須要加上組名(Group 的name)

Ok,這樣經過Group編碼也完成了,可是Group名是不能變的,如何動態的鏈接到各個Group呢?

其實能夠從message['path']裏面提取出Group的名字,而後把myRoom替換掉就行

代碼GitHub地址:https://github.com/shichaosc/gitskills/tree/master/jozzon

相關文章
相關標籤/搜索