Filipe Aleixo
Filipe Aleixo

Reputation: 4242

Django signals + channels: message not going through to client

I want a signal to be sent every time a .save() is made

from django.db import models
from django.forms.models import model_to_dict
from django.db.models.signals import post_save
from channels.layers import get_channel_layer
from django.core.serializers.json import DjangoJSONEncoder
from asgiref.sync import async_to_sync
import json

class DeribitFundingData(models.Model):
    time = models.DateTimeField()
    rate = models.FloatField()

    def __str__(self):
        return str(self.time)

def save_post(sender, instance, **kwargs):
    channel_layer = get_channel_layer()
    data = model_to_dict(instance)
    json_data = json.dumps(data, cls=DjangoJSONEncoder)
    async_to_sync(channel_layer.group_send)(
        "echo_group",
        {"type": "stream", "data": json_data},
    )

post_save.connect(save_post, sender=DeribitFundingData)

My consumer looks as follows, where stream is supposed to receive the data from save_post:

class StreamConsumer(AsyncConsumer):

    groups = ["echo_group"]

    async def websocket_connect(self, event):
        print("connected", event)
        await self.send({
            "type": "websocket.accept"
        })

    async def stream(self, event):
        data = event["message"]

        await self.send({
           'type': 'websocket.send',
           'text': data
        })

My .js:

<script>
    var loc = window.location
    var wsStart = "ws://"
    if (loc.protocol == 'https:'){
        wsStart = 'wss://'
    }
    var endpoint = wsStart + loc.host + "/websockets/"
    console.log(endpoint)

    socket = new WebSocket(endpoint);

    socket.onopen = function(message) {
        console.log("open", message);
      }

    socket.onmessage = function(message) {
        console.log("message", message);
    }

    socket.onerror = function(message) {
        console.log("error", message);
    }

    socket.onclose = function(message) {
        console.log("close", message);
    }
</script>

In the shell I see that the websockets connection was established. Although the messages I'm sending from post_save are not going through. What's wrong?

Upvotes: 1

Views: 676

Answers (1)

drec4s
drec4s

Reputation: 8077

You need to add a channel_layer to the echo_group when you first accept the connection:

    async def websocket_connect(self, event):
        print("connected", event)
        await self.channel_layer.group_add("echo_group",self.channel_name)
        await self.send({
            "type": "websocket.accept"
        })

Upvotes: 1

Related Questions