API Reference
Settings
CHANNELS_PRESENCE_MAX_AGE
Default
60
. Maximum age in seconds before a presence is considered expired.
Models
Room
from channels_presence.models import Room
Manager:
Room.objects.add(room_chanel_name, user_channel_name, user=None)
Add the given
user_channel_name
(e.g.consumer.channel_name
) to a Room with the nameroom_channel_name
. If provided, associate the authUser
as well. Creates a newRoom
instance if it doesn’t exist; creates any neededPresence
instance, and updates the channels group membership. Returns theroom
instance.Room.objects.remove(room_channel_name, user_channel_name)
Remove the given
user_channel_name
from the room withroom_channel_name
. Removes relevantPresence
instances, and updates the channels group membership.Room.objects.prune_presences(age_in_seconds=None)
Remove any
Presence
models whoselast_seen
timestamp is older thanage_in_seconds
(defaults tosettings.CHANNELS_PRESENCE_MAX_AGE
if not specified).Room.objects.prune_rooms()
Remove any rooms that have no associated
Presence
models.
Instance properties:
room.channel_name
The channel name associated with the group for this room.
Instance methods:
room.get_users()
Return a queryset with all of the unique authenticated users who are present in this room.
room.get_anonymous_count()
Return the number of non-authenticated sockets which are present in this room.
Presence
from channels_presence.models import Presence
Manager:
Presence.objects.touch(channel_name)
Updates the
last_seen
timestamp to now for all instances with the given channel name.Presence.objects.leave_all(channel_name)
Removes all
Presence
instances with the given channel name. Triggerschannels_presence.signals.presence_changed
for any changed rooms.
Instance properties:
presence.room
The room to which this Presence belongs
presence.channel_name
The consumer channel name associated with this Presence
presence.user
A
settings.AUTH_USER_MODEL
associated with this Presence, or Nonepresence.last_seen
Timestamp for the last time socket traffic was seen for this presence.
Decorators
touch_presence
from chanels_presence.decorators import touch_presence
Decorator for use on websocket.receive
handlers which updates the
last_seen
timestamp on any Presence
instances associated with the
client. If the message being sent is the literal JSON-encoded "heartbeat"
,
message processing stops and the decorator does not call the decorated
function. Note that this decorator is syncronous, so should only be used on
syncronous handlers.
from channels.generic.websocket import WebsocketConsumer
class MyConsumer(WebsocketConsumer):
@touch_presence
def receive(self, text_data=None, bytes_data=None):
pass
remove_presence
from chanels_presence.decorators import remove_presence
Decorator for use on websocket.disconnect
handlers which removes any
Presence
instances associated with the client. Note that this decorator is
syncronous, so should only be used on syncronous handlers.
from channels.generic.websocket import WebsocketConsumer
class MyConsumer(WebsocketConsumer):
@remove_presence
def disconnect(self, close_code):
pass
Signals
presence_changed
from channels_presence.signals import presence_changed
A Django signal dispatched on any addition or removal of a Presence
from a
Room
. Use it to track when users come and go.
Arguments sent with this signal:
room
The
Room
instance from which aPresence
was added or removed.added
The
Presence
instance which was added, orNone
.removed
The
Presence
instance which was removed, orNone
.bulk_change
If
True
, indicates that this was a bulk change in presence. More than one presence may have been added or removed, and particular instances will not be provided inadded
orremoved
arguments.
Example:
# app/signals.py
import json
from asgiref.sync import async_to_sync
from channels.layers import get_channel_layer
from channels_presence.signals import presence_changed
from django.dispatch import receiver
channel_layer = get_channel_layer()
@receiver(presence_changed)
def broadcast_presence(sender, room, **kwargs):
"""
Broadcast the new list of present users to the room.
"""
message = {
"type": "presence",
"payload": {
"channel_name": room.channel_name,
"members": [user.serialize() for user in room.get_users()],
"lurkers": room.get_anonymous_count(),
}
}
# Prepare a dict for use as a channel layer message. Here, we're using
# the type "forward.message", which will magically dispatch to the
# channel consumer as a call to the `forward_message` method.
channel_layer_message = {
"type": "forward.message",
"message": json.dumps(message)
}
async_to_sync(channel_layer.group_send)(room.channel_name, channel_layer_message)
# app/channels.py: App consumer definition
from channels.generic.websocket import WebsocketConsumer
class AppConsumer(WebsocketConsumer):
def forward_message(self, event):
"""
Utility handler for messages to be broadcasted to groups. Will be
called from channel layer messages with `"type": "forward.message"`.
"""
self.send(event["message"])