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 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_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_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.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_MODELassociated with this Presence, or None presence.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
Roominstance from which aPresencewas added or removed. added- The
Presenceinstance which was added, orNone. removed- The
Presenceinstance 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 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"])