Channels: get_channel_layer cannot get channel_layer in other process

Created on 2 May 2018  路  3Comments  路  Source: django/channels

Hi, I have a requirement, a task in the background collecting news in order to send to the same group front end. In the front end, many users connect to django-channels like this:

webSocketBridge.connect('/ws/aws');
webSocketBridge.listen(function(action, stream) { //read the news });

In django-channels I set a consumer class, the users can connect to django channels url '/ws/aws' and add to group 'aws':

class MyConsumer(AsyncJsonWebsocketConsumer):
    def connect(self):
        self.room_group_name = 'aws'
        async_to_sync(self.channel_layer.group_add)( self.room_group_name, self.channel_name)
        self.accept()

Then I use the django-apscheduler start a job which collecting news every hour and send news to front end which belongs to 'aws':

def news_job():
    channel_layer = get_channel_layer()
    async_to_sync(channel_layer.group_send)(
        'aws',
        { 'type': 'news_message',  'text': news }
    )

But when the job runs, the console prints AttributeError: 'NoneType' object has no attribute 'group_send', the get_channel_layer() could not get channels_layer.

blockeuser-response

Most helpful comment

You can't officially use the in-memory backend in Channels 2 any more - you can either:

  • Not use channels features and set CHANNEL_LAYERS = {} as you did, which will let applications run and websockets work but groups will not work
  • Use the Redis backend to have working groups

It was removed because channel layers now only support groups, and those are generally only useful if they work cross-process, hence an in-memory solution would only ever be useful for people who ran exactly one server process.

All 3 comments

Are your Django settings set up correctly? That error almost certainly means that CHANNEL_LAYERS is not set.

I install channels 2.0, I want to use memory as backend and set up CHANNEL_LAYERS like channels 1.x in my test enviroment:

ASGI_APPLICATION = 'config.routing.application'
CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "asgiref.inmemory.ChannelLayer",
    },
}

but the console print channels.exceptions.InvalidChannelLayerError: Cannot import BACKEND 'asgiref.inmemory.ChannelLayer' specified for default, I read docs of channels 2, I find no solution. At last I set the CHANNELS_LAYERS = {}.

You can't officially use the in-memory backend in Channels 2 any more - you can either:

  • Not use channels features and set CHANNEL_LAYERS = {} as you did, which will let applications run and websockets work but groups will not work
  • Use the Redis backend to have working groups

It was removed because channel layers now only support groups, and those are generally only useful if they work cross-process, hence an in-memory solution would only ever be useful for people who ran exactly one server process.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Ya2s picture Ya2s  路  22Comments

devxplorer picture devxplorer  路  24Comments

davidfstr picture davidfstr  路  18Comments

joshua-s picture joshua-s  路  30Comments

dgilge picture dgilge  路  30Comments