Files
2020-03-15 15:05:11 -06:00

221 lines
6.1 KiB
ReStructuredText

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 name ``room_channel_name``. If provided, associate the auth
``User`` as well. Creates a new ``Room`` instance if it doesn't exist;
creates any needed ``Presence`` instance, and updates the channels group
membership. Returns the ``room`` instance.
``Room.objects.remove(room_channel_name, user_channel_name)``
Remove the given ``user_channel_name`` from the room with
``room_channel_name``. Removes relevant ``Presence`` instances, and updates
the channels group membership.
``Room.objects.prune_presences(age_in_seconds=None)``
Remove any ``Presence`` models whose ``last_seen`` timestamp is older than
``age_in_seconds`` (defaults to ``settings.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. Triggers
``channels_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.
.. code-block:: python
from channels.generic.websocket import WebsocketConsumer
class MyConsumer(WebsocketConsumer):
@touch_presence
def receive(self, text_data=None, bytes_data=None):
pass
``remove_presence``
------------------------------------------------
.. code-block:: python
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.
.. code-block:: python
from channels.generic.websocket import WebsocketConsumer
class MyConsumer(WebsocketConsumer):
@remove_presence
def disconnect(self, close_code):
pass
Signals
~~~~~~~
``presence_changed``
----------------------------------------------
.. code-block:: python
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 a ``Presence`` was added or removed.
``added``
The ``Presence`` instance which was added, or ``None``.
``removed``
The ``Presence`` instance which was removed, or ``None``.
``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 in ``added`` or ``removed`` arguments.
Example:
.. code-block:: python
# 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)
.. code-block:: python
# 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"])