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]