Search code examples
pythondjangodjango-channels

Django channels - unable to subscribe to groups


I'm attempting to send consumers.py information to display on the client end outside of consumers.py.

I've referenced Send message using Django Channels from outside Consumer class this previous question, but the sub process .group_send or .group_add don't seem to exist, so I feel it's possible I'm missing something very easy.

Consumers.py

from channels.generic.websocket import WebsocketConsumer
from asgiref.sync import async_to_sync

class WSConsumer(WebsocketConsumer):
    def connect(self):
        async_to_sync(self.channel_layer.group_add)("appDel", self.channel_name)
        self.accept()

        self.render()

appAlarm.py

def appFunc(csvUpload):
    #csvUpload=pd.read_csv(request.FILES['filename'])
    csvFile = pd.DataFrame(csvUpload)
    colUsernames = csvFile.usernames
    print(colUsernames)

    channel_layer = get_channel_layer()

    for user in colUsernames:
        req = r.get('https://reqres.in/api/users/2')
        print(req)
        t = req.json()
        data = t['data']['email']
        print(user + " " + data)
        
        message = user + " " + data
        async_to_sync(channel_layer.group_send)(
        'appDel',
        {'type': 'render', 'message': message}
    )

It's throwing this error:

    async_to_sync(channel_layer.group_send)(
AttributeError: 'NoneType' object has no attribute 'group_send'

and will throw the same error for group_add when stripping it back more to figure out what's going on, but per the documentation HERE I feel like this should be working.


Solution

  • To anyone looking at this in the future, I was not able to use redis or even memurai in Windows OS due to cost. I ended up using server side events (SSE), specifically django-eventstream, and so far it's worked great as I didn't need the client to interact with the server, for a chat application this would not work.

    Eventstream creates an endpoint at /events/ the client can connect to and receive a streaming http response.

    Sending data from externalFunc.py:

    send_event('test', 'message', {'text': 'Hello World'})
    

    Event listener in HTML page:

    var es = new ReconnectingEventSource('/events/');
    
    es.addEventListener('message', function (e) {
        console.log(e.data);
    
        var source = new EventSource("/events/")
    
        var para = document.createElement("P");
        const obj = JSON.parse(event.data)
        para.innerText = obj.text;
        document.body.appendChild(para)
    
    }, false);
    
    es.addEventListener('stream-reset', function (e) {
    }, false);