1. 程式人生 > >django channels中 在customer之外使用channel_layer (以及channel_layer.group_send中type的意思)

django channels中 在customer之外使用channel_layer (以及channel_layer.group_send中type的意思)

channels文件中有Using Outside Of Consumers,介紹瞭如何在消費者類外使用channel_layer

from channels.layers import get_channel_layer
from asgiref.sync import async_to_sync

channel_layer = get_channel_layer()
async_to_sync(channel_layer.group_send)("chat", {"type": "chat.force_disconnect"})

這裡的type一度讓我很迷茫,之前在consumers類中,理解的是該類中的一個自定義的函式,但是都out of consumers 怎麼還用consumers類中的函式呢..

# 這裡附上一般的consumer類
class ChatConsumer(WebsocketConsumer):

    def connect(self):
        self.room_group_name = "test"
        async_to_sync(self.channel_layer.group_add)(self.room_group_name, self.channel_name)
        self.accept()

    def disconnect(self, close_code):
        async_to_sync(self.channel_layer.group_discard)(
            self.room_group_name,
            self.channel_name
        )

    def
receive(self, text_data):
text_data_json = json.loads(text_data) message = text_data_json['message'] async_to_sync(self.channel_layer.group_send)( self.room_group_name, { 'type': 'chat_message', # 這裡的type 實際上就是 下面的chat_message自定義函式 'message'
: message } ) def chat_message(self, event): message = event['message'] # Send message to WebSocket self.send(text_data=json.dumps({ 'message': "已傳送除錯資訊,請耐心等待回覆" }))

後來我在某位不知名大佬的部落格下提問後,大佬給我的回答讓我走出了衚衕,我提問的那篇部落格 ,他用的評論外掛,需要翻牆後才能看到,我這裡就貼張圖吧 大佬的解釋 看了他的解釋,豁然開朗~~ 實際上get_channel_layer() 函式獲得的是當前的websocket連線所對應的consumer類物件的channel_layer,因此,可以在consumer類中寫的函式,在外面也能呼叫. 我寫個示例,可以理解下:

# demo/consumers
# consumer類
class ChatConsumer(WebsocketConsumer):

    def connect(self):
        self.room_group_name = "test"
        async_to_sync(self.channel_layer.group_add)(self.room_group_name, self.channel_name)
        self.accept()

    def disconnect(self, close_code):
        async_to_sync(self.channel_layer.group_discard)(
            self.room_group_name,
            self.channel_name
        )

    def receive(self, text_data):
        text_data_json = json.loads(text_data)
        message = text_data_json['message']
        async_to_sync(self.channel_layer.group_send)(
            self.room_group_name,
            {
                'type': 'chat_message', # 這裡的type 實際上就是 下面的chat_message自定義函式
                'message': message
            }
        )

    def chat_message(self, event):
        message = event['message']
        # Send message to WebSocket
        self.send(text_data=json.dumps({
            'message': "已傳送除錯資訊,請耐心等待回覆"
        }))

    def send_message(self, event):
        message = event['message']
        # Send message to WebSocket
        self.send(text_data=json.dumps({
            'message': "啦啦啦~~"
        }))
# demo/outofconsumer
from channels.layers import get_channel_layer
channel_layer = get_channel_layer()
group_name='test'
# channel 內部會自動把 . 轉化成 _ 
async_to_sync(channel_layer.group_send)(group_name, {"type": "send.message", "message": payload['message']})    

這樣在呼叫outofconsumer時 就會給屬於該consumer的websocket連線傳送啦啦啦~~

本文純屬個人記錄,如果能幫到你,記得點贊~