1

I've got a django channels consumer communicating with a client. I've got a view from an external API that wants something from the client. From this view I want then to tell that consumer to ask a request to the client through his socket.

I'm currently exploring django rest framework but I can't find a way for now to directly ask anything to that consumer. Well I've got an idea but it involves creating another socket and communicate through channels' channel. But I wish I could get rid of this overload.

1 Answers1

2

From your reponse in the comments, it seems you want to send a message to the client through the consumer from your DRF view. You can check out the answer to a similar question.

First, you need to have a method in your consumer that sends a message back to the client:

...
async def send_alert(self, event):

    # Send message to WebSocket
    await self.send(text_data={
        'type': 'alert',
        'details': 'An external API api.external.com needs some data from you'
    })
...

So now you can send a message to this method. Assuming the client is connected to channel1, you can do this in your view:

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

channel_layer = get_channel_layer()
async_to_sync(channel_layer.send)("channel1", {
    "type": "send.alert"
})
...

async_to_sync usage

Anindya Manna
  • 49
  • 1
  • 8
Ken4scholars
  • 6,076
  • 2
  • 21
  • 38
  • I'm sorry but I forgot to ask how should I send the response I got from the client back to the API view... ? Should I update the question and undo acceptance ? – Guillaume Geoffrey Attia Jan 24 '19 at 10:29
  • That's a separate question so you're better off posting a new question as your original question has been answered – Ken4scholars Jan 24 '19 at 12:36
  • And for what is worth, I don't see any use sending a message from the consumer to the view. It's just like sending data from one view to another view which doesn't make any sense. If there's any logic to be called from the consumer, separate it from the view so it is accessible to both the view and consumer. The view should only handle request/response cycle – Ken4scholars Jan 24 '19 at 12:42
  • The view that needs to send something to the client through the consumer is a RestAPI (hopefully) with django rest framework. So the API cannot send anything directly through the opened socket used by the consumer. These 2 views are from 2 different logical parts in the project. Maybe I should not do it this way and handle it all directly in the consumer but I don't know how. – Guillaume Geoffrey Attia Jan 24 '19 at 13:34
  • Maybe you should post a question with your code and why you need to call the view from another part of the code because I'm still finding it difficult to think up a situation where that would be necessary. If they are separated into microservices then you can make a http request from the consumer (not necessarily directly from the consumer) to the endpoint of the second service. – Ken4scholars Jan 24 '19 at 14:09
  • Alright I posted another question with some code in it. https://stackoverflow.com/questions/54350826/how-to-integrate-channels-and-drf-together – Guillaume Geoffrey Attia Jan 24 '19 at 16:07