Constantly send data to client from server Constantly send data to client from server django django

Constantly send data to client from server


consumers.py

import asynciofrom channels.consumer import AsyncConsumerclass ChatConsumer(AsyncConsumer):    async def websocket_connect(self, event):        self.connected = True        print("connected", event)        await self.send({            "type": "websocket.accept"        })        while self.connected:            await asyncio.sleep(2)            obj = # do_something (Ex: constantly query DB...)             await self.send({                'type': 'websocket.send',                'text': # obj,            })    async def websocket_receive(self, event):        print("receive", event)    async def websocket_disconnect(self, event):        print("disconnected", event)        self.connected = False

Javascript

var loc = window.location;var wsStart = 'ws://';if (loc.protocol == 'https:') {    wsStart = 'wss://'}var endpoint = wsStart + loc.host + loc.pathname;var socket = new WebSocket(endpoint);socket.onmessage = function(e){    console.log("message", e);};socket.onopen = function(e){    console.log("open", e);};socket.onerror = function(e){    console.log("error", e)};socket.onclose = function(e){    console.log("close", e)};

All you need to do is just modify obj and send it. You can extend this function as much as you want. So, right now I'm interested in getting the latest inserted row in my PostgreSQL and injecting that row into my WebSocket. I can query my DB every 2 seconds as it was specified by await asyncio.sleep(2), and inject it into the Front-End socket.


Using channels==1.* and Django==1.* you can use the threading module for example:

# Some view.pyimport threadingimport timeclass Publisher(threading.Thread):    def __init__(self, reply_channel, frequency=0.5):        super(Publisher, self).__init__()        self._running = True        self._reply_channel = reply_channel        self._publish_interval = 1.0 / frequency    def run(self):        while self._running:           self._reply_channel.send({'text': 'some data'})           time.sleep(self._publish_interval)    def stop(self):        self._running = Falsepublishers = {}def ws_connect(message):    message.reply_channel.send({'accept': True})    publisher = Publisher(reply_channel=message.reply_channel)    publisher.start()    publishers[message.reply_channel] = publisherdef ws_disconnect(message):    publisher = publishers[message.reply_channel]    publisher.stop()    del publishers[message.reply_channel]