[REDIS] 어떻게 장고 - 셀러리 3 작업에서 채널 2.X 그룹 메시지를 보낼 수 있습니까?
REDIS어떻게 장고 - 셀러리 3 작업에서 채널 2.X 그룹 메시지를 보낼 수 있습니까?
나는 채널 메시지를 전송하는 연기해야합니다. 여기 내 코드는 다음과 같습니다
# consumers.py
class ChatConsumer(WebsocketConsumer):
def chat_message(self, event):
self.send(text_data=json.dumps(event['message']))
def connect(self):
self.channel_layer.group_add(self.room_name, self.channel_name)
self.accept()
def receive(self, text_data=None, bytes_data=None):
send_message_task.apply_async(
args=(
self.room_name,
{'type': 'chat_message',
'message': 'the message'}
),
countdown=10
)
# tasks.py
@shared_task
def send_message_task(room_name, message):
layer = get_channel_layer()
layer.group_send(room_name, message)
작업이 실행되고 난 오류를 볼 수 있지만, 메시지가 전송되지 않습니다. 내가 소비자 클래스 메소드로 보낼 경우에만 작동합니다.
또한 AsyncWebsocketConsumer을 사용하고 AsyncToSync (layer.group_send)로 전송했습니다. 그것으로 오류 "당신은 비동기 이벤트 루프와 같은 스레드에서 AsyncToSync을 사용할 수 없습니다 -. 단지 직접 비동기 기능을 기다리고 있습니다"
그럼 난 비동기로 send_message_task을 선언하고 await를 사용하여 시도. 아무것도 (오류없이) 다시 발생하고 작업이 전혀 실행되고 있는지 확실하지 않습니다.
다음 버전은 다음과 같습니다
Django==1.11.13
redis==2.10.5
django-celery==3.2.2
channels==2.1.2
channels_redis==2.2.1
설정 :
REDIS_HOST = os.getenv('REDIS_HOST', '127.0.0.1')
BROKER_URL = 'redis://{}:6379/0'.format(REDIS_HOST)
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {
"hosts": ['redis://{}:6379/1'.format(REDIS_HOST)],
},
},
}
어떤 아이디어?
UPD : 그냥은 레디 스 채널 층이 입수해온되지만 그것의 group_send 메소드가 호출되지 않고 바로 건너 뛸 것을 알아 냈다.
UPD 2 : 콘솔 작품에서 AsyncToSync (layer.group_send)를 사용하여 전송. apply_async도 작동하지 않고 작업을 호출. 다만 직접 비동기 기능을 기다리고 있습니다 -하지만 apply_async로 실행하면 오류가 당신은 비동기 이벤트 루프와 같은 스레드에서 AsyncToSync을 사용할 수 없습니다됩니다. 비동기로 작업을 정의하고 await를 사용하는 것은 물론 모든 것을 나누기.
해결법
-
==============================
1.어쩌면이 시작 질문하지만,이 힘의 도움에 직접 대답은하지 않습니다. 당신이 예외가 발생하면 "당신은 비동기 이벤트 루프와 같은 스레드에서 AsyncToSync을 사용할 수 없습니다 - 그냥 직접 비동기 기능을 기다리고 있습니다"그때는 아마이 몇 가지 있습니다 :
어쩌면이 시작 질문하지만,이 힘의 도움에 직접 대답은하지 않습니다. 당신이 예외가 발생하면 "당신은 비동기 이벤트 루프와 같은 스레드에서 AsyncToSync을 사용할 수 없습니다 - 그냥 직접 비동기 기능을 기다리고 있습니다"그때는 아마이 몇 가지 있습니다 :
AsyncToSync는 외부 이벤트 루프를 감지하고 방해하지 않도록 결정을 내리는 것으로 보인다.
해결 방법은 직접 외부 이벤트 루프에서 비동기 호출을 포함하는 것입니다. 예제 코드 아래, 그러나 가장 귀하의 상황을 확인하는 것입니다 그 외부 루프가 실행되는 ...
loop = asyncio.get_event_loop() loop.create_task(layer.group_send(room_name, {'type': 'chat_message', 'message': message}))
-
==============================
2.모든 채널 층 방법은 비동기이기 때문에 채널 레이어를 사용하면 연결에 async_to_sync () 래퍼가 필요합니다.
모든 채널 층 방법은 비동기이기 때문에 채널 레이어를 사용하면 연결에 async_to_sync () 래퍼가 필요합니다.
def connect(self): async_to_sync(self.channel_layer.group_add( self.room_name, self.channel_name) self.accept()
당신의 셀러리 작업에서 메시지를 보내와 같은 거래.
@shared_task def send_message_task(room_name, message): channel_layer = get_channel_layer() async_to_sync(channel_layer.group_send)( room_name, {'type': 'chat_message', 'message': message} )
또한 당신은 다음과 같이) (수신하여 소비자의에서 셀러리 작업을 호출 할 수 있습니다 :
send_message_task.delay(self.room_name, 'your message here')
이 스레드에 설명 된대로 새 버전으로 채널과 다프네를 업그레이드하는 데 필요한 AsyncToSync 오류에 대해서.
-
==============================
3.나는 못생긴 비효율적 인 의사 결정을 찾았지만, 그것을 작동합니다 :
나는 못생긴 비효율적 인 의사 결정을 찾았지만, 그것을 작동합니다 :
@shared_task def send_message_task(room_name, message): def sender(room_name, message): channel_layer = get_channel_layer() AsyncToSync(channel_layer.group_send)( room_name, {'type': 'chat_message', 'message': message} ) thread = threading.Thread(target=sender, args=(room_name, message,)) thread.start() thread.join()
누군가가 그것을 개선 할 수 있다면, 나는 감사합니다.
-
==============================
4.코드에서 문제는 당신이 당신의 타입 chat_message에 밑줄을 사용한다는 것입니다. 난 당신이 문서에 그것을 놓친 생각 :
코드에서 문제는 당신이 당신의 타입 chat_message에 밑줄을 사용한다는 것입니다. 난 당신이 문서에 그것을 놓친 생각 :
귀하의 경우 그래서, 유형 chat.message 될 것입니다
{ 'type': 'chat.message', 'message': 'the message' }
from https://stackoverflow.com/questions/51024893/how-do-i-send-channels-2-x-group-message-from-django-celery-3-task by cc-by-sa and MIT license
'REDIS' 카테고리의 다른 글
[REDIS] 왜 redisTemplate.opsForValue (). NOT NULL 항상) (얻을? (0) | 2020.02.22 |
---|---|
[REDIS] 레디 스와 통신 할 컬을 남용 (0) | 2020.02.20 |
[REDIS] SSL을 통해 레디 스에 셀러리 연결 한 후 응답이 없습니다 (0) | 2020.02.17 |
[REDIS] 활성 작업 / 백그라운드 작업에 파일 전달 (0) | 2020.02.16 |
[REDIS] 레디 스에게 평가 명령을 실행하는 것은 nodeJS에서 루아 스크립트를 실행하려면 (0) | 2020.02.15 |