django channels中 在customer之外使用channel_layer (以及channel_layer.group_send中type的意思)
阿新 • • 發佈:2018-12-09
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連線傳送啦啦啦~~
本文純屬個人記錄,如果能幫到你,記得點贊~