Reputation: 7311
I have a long running task running on Celery. When it is done, I want to send a message to the browser that will simply instruct it to refresh the page. To do that, I want to use channels V2.
It's not clear from the docs how to achieve that.
This is what I have in my background task, but I'm not sure how to set up the Consumer
@shared_task
def my_task():
time.sleep(5)
Channel('my-background-task').send({"refresh": True})
Upvotes: 3
Views: 1887
Reputation: 6107
class ReloadConsumer(WebsocketConsumer):
def connect(self):
self.group_name = self.scope['user']
print(self.group_name) # use this for debugging not sure what the scope returns
# Join group
async_to_sync(self.channel_layer.group_add)(
self.group_name,
self.channel_name
)
self.accept()
def disconnect(self, close_code):
# Leave group
async_to_sync(self.channel_layer.group_discard)(
self.group_name,
self.channel_name
)
def reload_page(self, event):
# Send message to WebSocket
self.send(text_data=json.dumps({
'reload': True
}))
self.disconnect()
Then when your celery task is completed you send a reload_page message to the relevant group.
@shared_task
def my_task():
... do your task ...
group_name = get_user_name() # Find out way to get same as what is printed on connect()
channel_layer = get_channel_layer()
# Trigger reload message sent to group
async_to_sync(channel_layer.group_send)(
group_name,
{'type': 'reload_page'}
)
Once you can successfully create a group for the user when they start the celery task, then send a message to the user's group on completion it's as simple as adding this script:
webSocket.onmessage = function() {
window.location.reload();
}
Upvotes: 3