简体   繁体   English

通过 celery 向 django-channels 发送消息

[英]Sending messages to django-channels via celery

So I have a scheduled celery beat task (celery.py):所以我有一个预定的 celery beat 任务(celery.py):

@app.on_after_configure.connect 
def setup_periodic_tasks(sender,
**kwargs):
    sender.add_periodic_task(10.0, test_event, name='test')

And the task (events/tasks.py):和任务(events/tasks.py):

@shared_task
def test_event():
    from .models import Event
    Event.objects.create()

When the event is created, a receiver is fired, that should send a message to a channels group (events/receivers.py):创建事件时,会触发接收器,该接收器应向通道组 (events/receivers.py) 发送消息:

@receiver(post_save, sender=Event)
def event_post_add(sender, instance, created, *args, **kwargs):
    if created:
        print("receiver fired")
        Group("test").send({
            "text": json.dumps({
                'type': 'test',
            })
        })

The main problem is that the receiver is being fired in the celery beat process, and nothing is getting sent via django channels.主要问题是接收器在 celery beat 过程中被触发,并且没有任何内容通过 django 通道发送。 No error messages, nothing, it's simply not being sent.没有错误消息,没有,只是没有被发送。

How can I integrate these two so that I will be able to send messages to channels from celery background processes?如何将这两个集成在一起,以便我能够从 celery 后台进程向通道发送消息?

hi i dont know if you found a solution or not.嗨,我不知道您是否找到了解决方案。 but as i was stuck on this problem myself so i tried a work around.但由于我自己被困在这个问题上,所以我尝试了一个解决方法。 i created a view for the message that needs to be send by websocket and make a request to it from celery beat the view:我为需要通过 websocket 发送的消息创建了一个视图,并从 celery 向它发出请求击败了视图:

def send_message(request,uuid,name):
print('lamo')
ty = f"uuid_{uuid}"
data={
    'message':f'{name} Driver is now Avaliable',
    'sender':'HQ',
    'id':str(uuid),
    'to':str(uuid),
    'type':'DriverAvailable',
}
channel_layer = get_channel_layer()
async_to_sync(channel_layer.group_send)(
    ty,
    {'type':'chat_message',
    'message':data,
    }
)

and the task:和任务:

def my_task():
list=[]
for d in Driver_api.objects.all():
    if d.available_on !=None:
        if d.available_on <= timezone.now():
            d.available_on = None
            d.save()
        uuid = str(d.user.uuid)
        requests.get(f'{DOMAIN}message/sendMessage/{uuid}/{d.name}')
    logger.info('Adding {0}'.format(d.user.uuid))

return list

sorry for any neglects or overlooks in my approach to the problem.对于我解决问题的方法中的任何疏忽或疏忽,我深表歉意。

Signals are actually not being asynchronous in Django.信号实际上在 Django 中不是异步的。 So in:所以在:

@shared_task
def test_event():
    from .models import Event
    Event.objects.create() # This will fire a signal and the signal will 
                           # still be interpreted by celery

The only nice approach I know would be if your backend would listen on rabbitmq messages.我知道的唯一好方法是您的后端是否会监听 rabbitmq 消息。 A simple and nasty approach would be to fire a request to a view in django.一种简单而讨厌的方法是向 Django 中的视图发出请求。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM