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 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
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"])