Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unsubscribe from consumer issue #221

Open
hishnash opened this issue Feb 12, 2025 · 0 comments
Open

Unsubscribe from consumer issue #221

hishnash opened this issue Feb 12, 2025 · 0 comments

Comments

@hishnash
Copy link
Member

Discussed in #196

Originally posted by Ilyes-git January 28, 2024
Hello everyone,

I'm new to channels, I've tried to follow the readme to the letter, but I still haven't managed to solve part of the problem.
My goal is simple, "I want to have the ability, to receive messages in real time for the logged in user."

To give you some context, let me share with you my current code:

class Message(models.Model):
    sender = models.ForeignKey(User, on_delete=models.CASCADE, related_name="sent_messages")
    receiver = models.ForeignKey(User, on_delete=models.CASCADE, related_name="received_messages")
    message = models.CharField(max_length=1000)
    datetime = models.DateTimeField(auto_now_add=True)
class MessageSerializer(serializers.ModelSerializer):
    class Meta:
        model = Message
        fields = ALL_FIELDS
# consumers.py
from chat_app.models import Message
from chat_app.serializers import MessageSerializer
from djangochannelsrestframework.decorators import action
from djangochannelsrestframework.generics import GenericAsyncAPIConsumer
from djangochannelsrestframework.observer import model_observer


class MessageConsumer(GenericAsyncAPIConsumer):
    queryset = Message.objects.all()
    serializer_class = MessageSerializer

    @model_observer(Message)
    async def message_activity(
        self,
        message: MessageSerializer,
        observer=None,
        **kwargs,
    ):
        await self.send_json(message)

    @message_activity.groups_for_signal
    def message_activity(self, instance: Message, **kwargs):
        yield f"-user-{instance.receiver.id}"

    @message_activity.groups_for_consumer
    def message_activity(self, receiver, list=False, **kwargs):
        # receiver = self.scope["user"].id # => AttributeError: 'ModelObserver' object has no attribute 'scope'
        yield f"-user-{receiver}"

    @action()
    async def subscribe_to_send_messages(self, **kwargs):
        if "user" in self.scope and self.scope["user"].is_authenticated:
            await self.message_activity.subscribe(receiver=self.scope["user"].id)
            return {}, 201

    @action()
    async def unsubscribe_from_send_messages(self, **kwargs):
        await self.message_activity.unsubscribe(receiver=self.scope["user"].id)
        return {}, 204

Actions :

  • subscribe_to_send_messages works perfectly 👌
  • unsubscribe_from_send_messages doesn't work 🙁

Question :
1 - in @message_activity.groups_for_consumer decorator I tried to use self.scope like mentioned on the documentation, but it doesn't seem to work (maybe the doc isn't up to date?).
2 - The big issue for me : How to make unsubscribe_from_send_messages work, am I making a mistake somewhere?

Thanks in advance for your help 🙏

Sources:
https://djangochannelsrestframework.readthedocs.io/en/latest/examples/filtered_model_observer.html
https://nilcoalescing.com/blog/BuildingARealtimeSocialNetworkUsingDjangoChannels/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant