Reputation: 4242
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
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