API Reference
Settings
CHANNELS_PRESENCE_MAX_AGEDefault
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 authUseras well. Creates a newRoominstance if it doesn’t exist; creates any neededPresenceinstance, and updates the channels group membership. Returns theroominstance.Room.objects.remove(room_channel_name, user_channel_name)Remove the given
user_channel_namefrom the room withroom_channel_name. Removes relevantPresenceinstances, and updates the channels group membership.Room.objects.prune_presences(age_in_seconds=None)Remove any
Presencemodels whoselast_seentimestamp is older thanage_in_seconds(defaults tosettings.CHANNELS_PRESENCE_MAX_AGEif not specified).Room.objects.prune_rooms()Remove any rooms that have no associated
Presencemodels.
Instance properties:
room.channel_nameThe 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_seentimestamp to now for all instances with the given channel name.Presence.objects.leave_all(channel_name)Removes all
Presenceinstances with the given channel name. Triggerschannels_presence.signals.presence_changedfor any changed rooms.
Instance properties:
presence.roomThe room to which this Presence belongs
presence.channel_nameThe consumer channel name associated with this Presence
presence.userA
settings.AUTH_USER_MODELassociated with this Presence, or Nonepresence.last_seenTimestamp 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:
roomThe
Roominstance from which aPresencewas added or removed.addedThe
Presenceinstance which was added, orNone.removedThe
Presenceinstance which was removed, orNone.bulk_changeIf
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 inaddedorremovedarguments.
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"])