Multiplex results from (Django-Channels)

83 views
Skip to first unread message

Yarnball

unread,
Apr 25, 2017, 8:13:30 PM4/25/17
to Django users
Hi,

I've currently setup Django channels to receive all the `messages` from a single `room`. However, I would like to set it up to receive `messages` from several rooms. In DRF, I'd use serializers to achieve this. However, in sockets, I am unsure how I would do it.

What is the correct

EG from chat rooms entitled `Foo` and `Bar` would look like this:

[
   
{
       
"label": "Foo",
       
"pk": 5,
       
"message": [
           
{
               
"handle": "Bruce",
               
"message": "Yo"
           
},
           
{
               
"handle": "Sol",
               
"message": "Hey"
           
}
       
]
   
},
   
{
       
"label": "Bar",
       
"pk": 10,
       
"message": [
           
{
               
"handle": "Sol",
               
"message": "Hi"
           
},
           
{
               
"handle": "Alfred",
               
"message": "Yo"
           
}
       
]
   
}
]

# consumers.py

@channel_session
def ws_connect(message):
    prefix
, label = message['path'].strip('/').split('/')
    room
= Room.objects.get(label=label)
    chathistory
= room.messages.all().order_by('timestamp')
   
Group('chat-' + label).add(message.reply_channel)
    message
.channel_session['room'] = room.label
    message
.reply_channel.send({'text': json.dumps([msg.as_dict() for msg in chathistory.all()])})


# models .py

class Room(models.Model):
    name
= models.TextField()
    label
= models.SlugField(unique=True)

class Message(models.Model):
    room
= models.ForeignKey(Room, related_name='messages')
    handle
= models.TextField()
    message
= models.TextField()
    timestamp
= models.DateTimeField(default=timezone.now, db_index=True)
   
def __unicode__(self):
       
return '[{timestamp}] {handle}: {message}'.format(**self.as_dict())


   
@property
   
def formatted_timestamp(self):
       
return self.timestamp.strftime("%H:%M:%S")
   
   
def as_dict(self):
       
return {'pk':self.pk, 'handle': self.handle, 'message': self.message, 'timestamp': self.formatted_timestamp}




Andrew Godwin

unread,
Apr 25, 2017, 8:25:46 PM4/25/17
to django...@googlegroups.com
Hi - I'll only reply to this thread, as you seem to have posted it twice with different subjects.

If you're going with the groups approach, as it seems you are, you need to add the user to multiple groups, one for each room, and then stick the room name in the group sends so you can distinguish them.

Andrew

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/153fb077-46b8-4e13-ab6d-d0a7d4f4dd65%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Message has been deleted

Yarnball

unread,
Apr 26, 2017, 3:16:34 AM4/26/17
to Django users
Thanks Andrew. I deleted the other post. I'm do not quite follow. 

I don't have a "user" key anywhere. And do I need to do a for loop to get the results? An example would be great. 

Cheers

Andrew Godwin

unread,
Apr 26, 2017, 1:50:07 PM4/26/17
to django...@googlegroups.com
When the connection comes in, you put them in a group based on the URL like this:

Group('chat-' + label).add(message.reply_channel)

Instead, if you want multiple rooms down one WebSocket, you need to add them to a group for all of the rooms that the connection should receive messages for. Either by stuffing multiple names in the URL, or by having commands sent down the socket and handled in the websocket.receive handler to add/remove from groups.

There's an example that shows some of this stuff here: https://github.com/andrewgodwin/channels-examples/tree/master/multichat

Andrew

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.

Yarnball

unread,
Apr 26, 2017, 7:49:53 PM4/26/17
to Django users
Thanks Andrew. I took your advice. I cloned and looking into the example, and tried what you suggested. 

In my case, the chat is persistent.

I will not be doing it via URL, instead I'm doing a queryset to get all the rooms a user belongs to.

However, it still isn't working. Could you please advise?

@channel_session
def ws_connect(message):
    listrooms
= User.objects.filter(chat__isnull=False).values('chat')
    # `listrooms` gives the PK fields of the chat rooms

    chathistory = room.messages.all().order_by('timestamp')

   
Group('chat-' + listrooms).add(message.reply_channel)
    message.channel_session['listrooms'] = list(set(message.channel_session['listrooms']).union([room.id]))

    message
.reply_channel.send({'text': json.dumps([msg.as_dict() for msg in chathistory.all()])})




@channel_session
def ws_receive(message):
    listrooms
= User.objects.filter(chat__isnull=False).values('chat')
    data
= json.loads(message['text'])
    m
= listrooms.messages.create(handle=data['handle'], message=data['message'])
   
Group('chat-'+ listrooms).send({'text': json.dumps([m.as_dict()])})

Andrew Godwin

unread,
Apr 26, 2017, 7:59:54 PM4/26/17
to django...@googlegroups.com
I only have limited time for free advice, unfortunately, so I can't help you write everything! However, it looks like your problem is that you are trying to add to a group called:

'chat-' + listrooms

Where listrooms is a queryset - that doesn't make any sense. You need a for loop instead.

Andrew

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
Message has been deleted

Yarnball

unread,
Apr 26, 2017, 10:25:57 PM4/26/17
to Django users
I do appreciate the bit of direction youve provided. And if you're asking to be paid, then sorry but I'm working free on a community project so it isn't such an option. Also why it would be good to get help on this minor task.

I'm almost there :)

I took your advice and put it in a loop. I am seeing the result, but getting a `TypeError: <Room: super> is not JSON serializable`

@channel_session

def ws_connect(message):
    room_id
= Tag.objects.filter(owner=1).filter(chat__isnull=False).values('chat__label').distinct()
   
print('I see values here', room_id)
   
for i in room_id:
       
try:
            room
= Room.objects.get(label=i['chat__label'])

            chathistory
= room.messages.all().order_by('timestamp')

           
Group('chat-' ).add(message.reply_channel)
            message
.channel_session['room'] = room
            message
.reply_channel.send({'text': json.dumps([msg.as_dict() for msg in chathistory.all()])})


       
except Exception as e:
           
print (str(e), ' Never happened')
           
pass


@channel_session
def ws_receive(message):
    label
= message.channel_session['room']
    room
= Room.objects.get(label=label)

    data
= json.loads(message['text'])

    m
= room.messages.create(handle=data['handle'], message=data['message'])
   
Group('chat-'+label).send({'text': json.dumps([m.as_dict()])})

Avraham Serour

unread,
Apr 27, 2017, 5:01:04 AM4/27/17
to django-users
You should just get the room object attribute you need, like name or id, instead of concatenating the whole object

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
Reply all
Reply to author
Forward
0 new messages