17👍
consumers.py
import asyncio
from channels.consumer import AsyncConsumer
class 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.
0👍
Using channels==1.* and Django==1.* you can use the threading module for example:
# Some view.py
import threading
import time
class 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 = False
publishers = {}
def ws_connect(message):
message.reply_channel.send({'accept': True})
publisher = Publisher(reply_channel=message.reply_channel)
publisher.start()
publishers[message.reply_channel] = publisher
def ws_disconnect(message):
publisher = publishers[message.reply_channel]
publisher.stop()
del publishers[message.reply_channel]
- Django rest auth email instead of username
- Django 1.9 drop foreign key in migration
- Datetime Field Received a Naive Datetime
- Using Node.js with Django and Backbone.js
0👍
A little late to the party here, but when it comes to Django you should always try to do things "their way" first…
So, to do this I simply used Django Channels. My client sends a message to the server, which the server then responds to with the needed database info. It looks as follows:
class SettingsConsumer(WebsocketConsumer):
def connect(self):
self.accept()
def disconnect(self, close_code):
pass
def receive(self, text_data):
settings = get_settings(self.scope["user"])
self.send(
text_data=json.dumps(
{
"playMode": settings.play_mode,
"isRecording": settings.is_recording,
}
)
)
Now, as for the JS to trigger constant events… I simply use SetInterval to request updates from the consumer every .25s!
My logic is that it’s the client so if it’s doing a little extra work no biggie, as the server is gonna be responding anyways. The JS looks as follows…
const chatSocket = new WebSocket(
'ws://'
+ window.location.host
+ '/ws/macros/update/'
);
chatSocket.onmessage = function(e) {
const data = JSON.parse(e.data);
if(data["playMode"] == true) {
$('#playmode-checkbox').attr('checked', true);
} else {
$('#playmode-checkbox').attr('checked', false);
}
if(data["isRecording"] == true) {
$('#recording-checkbox').attr('checked', true);
} else {
$('#recording-checkbox').attr('checked', false);
}
};
chatSocket.onclose = function(e) {
console.error('Chat socket closed unexpectedly');
};
window.setInterval(function() {
chatSocket.send(JSON.stringify({
'message': "start"
}));
}, 250);
And yes, you can do more to make this more async-friendly and optimized. But, you asked for simple and working so I hope this helps!
- Django: "Too many values to unpack" when calling user.objects.get()
- Is not JSON serializable – django social auth Facebook login