Django channels load previous messages - django

I am in the process of building a simple chat application and have already managed to make a functioning chat that stores sent messages in a model. However, I am struggling to retrieve previous messages.
consumers.py
def old_messages(self):
self.room_name = self.scope['url_route']['kwargs']['room_name']
room = ChatRoom.objects.get(room_name=self.room_name)
messages = ChatMessage.objects.filter(room=room)
content = {
'command': 'old'
}
return content
room.html
chatSocket.onopen = function(e) {
console.log("open",e)
old_messages()
};
function old_messages() {
chatSocket.send(JSON.stringify({
'command': 'old_messages'
}));
};
chatSocket.onmessage = function(e) {
const data = JSON.parse(e.data);
document.querySelector('#chat-log').value += (data.message + '\n');
};
document.querySelector('#chat-message-submit').onclick = function(e) {
const messageInputDom = document.querySelector('#chat-message-input');
const message = messageInputDom.value;
chatSocket.send(JSON.stringify({
'message': message,
'command': 'fetch_messages'
}));
messageInputDom.value = '';
};
Whenever I call old_messages() I get the error message = text_data_json['message']
KeyError: 'message' which refers to this chunk of code
def receive(self, text_data):
text_data_json = json.loads(text_data)
message = text_data_json['message']

Related

Uncaught DOMException: Failed to execute 'send' on 'WebSocket': Still in CONNECTING state

I am trying to stream video. The script work fine locally but gives following error when i moved to server
Uncaught DOMException: Failed to execute 'send' on 'WebSocket': Still in CONNECTING state.
at sendMessage (https://website.com/video:67:24)
at drawCanvas (https://website.com/video:59:17)
at HTMLButtonElement.<anonymous> (https://website.com/video:63:17)
Here is script i am using
<script type="text/javascript">
var socket = new WebSocket('ws://localhost:8888/websocket');
$(document).ready(function () {
let video = document.getElementById('video');
let canvas = document.getElementById('canvas');
let context = canvas.getContext('2d');
let draw_canvas = document.getElementById('detect-data');
let draw_context = draw_canvas.getContext('2d');
let image = new Image();
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia({video: true}).then(function (stream) {
video.srcObject = stream;
video.play();
});
}
function drawCanvas() {
context.drawImage(video, 0, 0, 600, 450);
sendMessage(canvas.toDataURL('image/png'));
}
document.getElementById("start-stream").addEventListener("click", function () {
drawCanvas();
});
function sendMessage(message) {
socket.send(message);
}
socket.onmessage = function (e) {
image.onload = function () {
console.log(e)};
};
})
</script>
In server I changed to var socket = new WebSocket('wss://10.0.1.232:8888/websocket');
Here is code for websocket
class WSHandler(tornado.websocket.WebSocketHandler):
def open(self):
print ('new connection')
def on_message(self, message):
from sub_app.py_files.detect import get_face_detect_data
image_data = get_face_detect_data(message)
if not image_data:
image_data = message
self.write_message(image_data)
def on_close(self):
print ('connection closed')
def check_origin(self, origin):
return True
application = tornado.web.Application([
(r'/websocket', WSHandler),
])
if __name__ == "__main__":
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(8888)
myIP = socket.gethostbyname(socket.gethostname())
print ('*** Websocket Server Started at %s***' % myIP)
tornado.ioloop.IOLoop.instance().start()

STUN/TURN server configuration for Django channels with WebRTC

I developed using django channels to implement video chat and message chat.(I was referring to a YouTuber's course.)
When I first completed the development, I noticed that webrtc works only in the local network, and I found out that a stun/turn server was needed.
So, I created a separate EC2 and built the stun/turn server and set this to the RTCPeerconnection in the web server.
Stun/turn server test in Trickle ICE is good.
But My video call still works only within the local network. And even within the same network, the connection was very slow.
Server overall configuration.(Webserver with SSL application loadbalancer)
Coturn config
# /etc/default/coturn
TURNSERVER_ENABLED=1
# /etc/turnserver.conf
# STUN server port is 3478 for UDP and TCP, and 5349 for TLS.
# Allow connection on the UDP port 3478
listening-port=3478
# and 5349 for TLS (secure)
tls-listening-port=5349
# Require authentication
fingerprint
lt-cred-mech
server-name=mysite.com
realm=mysite.com
# Important:
# Create a test user if you want
# You can remove this user after testing
user=myuser:userpassword
total-quota=100
stale-nonce=600
# Path to the SSL certificate and private key. In this example we will use
# the letsencrypt generated certificate files.
cert=/etc/letsencrypt/live/stun.mysite.com/cert.pem
pkey=/etc/letsencrypt/live/stun.mysite.com/privkey.pem
# Specify the allowed OpenSSL cipher list for TLS/DTLS connections
cipher-list="~~~~~-SHA512:~~~~~SHA512:~~~~~-SHA384:~~~~~SHA384:~~~-AES256-SHA384"
# Specify the process user and group
proc-user=turnserver
proc-group=turnserver
main.js in Web Server
let mapPeers = {};
let usernameInput = document.querySelector('#username');
let btnJoin = document.querySelector('#btn-join');
let username;
let webSocket;
const iceConfiguration = {
iceServers: [
{ urls:'stun:stun.mysite.com' },
{
username: 'myuser',
credential: 'userpassword',
urls: 'turn:turn.mysite.com'
},
]
}
function webSocketOnMessage(event) {
let parsedData = JSON.parse(event.data);
let peerUsername = parsedData['peer'];
let action = parsedData['action'];
if (username === peerUsername){
return;
}
let receiver_channel_name = parsedData['message']['receiver_channel_name'];
if (action === 'new-peer'){
createOfferer(peerUsername, receiver_channel_name);
return;
}
if (action === 'new-offer'){
let offer = parsedData['message']['sdp']
createAnswerer(offer, peerUsername, receiver_channel_name);
return;
}
if (action === 'new-answer'){
let answer = parsedData['message']['sdp'];
let peer = mapPeers[peerUsername][0];
peer.setRemoteDescription(answer);
return;
}
// console.log('message : ', message)
}
btnJoin.addEventListener('click', () => {
username = usernameInput.value;
console.log('username : ', username);
if (username === ''){
return;
}
usernameInput.value = '';
usernameInput.disabled = true;
usernameInput.style.visibility = 'hidden';
btnJoin.disabled = true;
btnJoin.style.visibility = 'hidden';
let labelUsername = document.querySelector('#label-username');
labelUsername.innerHTML = username;
let loc = window.location;
let wsStart = 'ws://';
if (loc.protocol === 'https:'){
wsStart = 'wss://';
}
let endpoint = wsStart + loc.host + loc.pathname + 'ws/';
console.log(loc.host)
console.log(loc.pathname)
console.log('endpoint: ', endpoint);
webSocket = new WebSocket(endpoint);
console.log('--------', webSocket)
webSocket.addEventListener('open', (e) => {
console.log('Connection opened!');
sendSignal('new-peer', {});
});
webSocket.addEventListener('message', webSocketOnMessage);
webSocket.addEventListener('close', (e) => {
console.log('Connection closed!', e)
});
})
// Media
let localStream = new MediaStream();
const constraints = {
'video': true,
'audio': true
}
const localVideo = document.querySelector('#local-video');
const btnToggleAudio = document.querySelector('#btn-toggle-audio');
const btnToggleVideo = document.querySelector('#btn-toggle-video');
let userMedia = navigator.mediaDevices.getUserMedia(constraints)
.then(stream => {
localStream = stream;
localVideo.srcObject = localStream;
localVideo.muted = true;
let audioTracks = stream.getAudioTracks();
let videoTracks = stream.getVideoTracks();
audioTracks[0].enabled = true;
videoTracks[0].enabled = true;
btnToggleAudio.addEventListener('click', () => {
audioTracks[0].enabled = !audioTracks[0].enabled;
if (audioTracks[0].enabled){
btnToggleAudio.innerHTML = 'Audio mute'
return;
}
btnToggleAudio.innerHTML = 'Audio unmute'
});
btnToggleVideo.addEventListener('click', () => {
videoTracks[0].enabled = !videoTracks[0].enabled;
if (videoTracks[0].enabled){
btnToggleVideo.innerHTML = 'Video off'
return;
}
btnToggleVideo.innerHTML = 'Video on'
});
})
.catch(error => {
console.log('Error accessing media devices', error);
});
// Message
let btnSendMsg = document.querySelector('#btn-send-msd');
let messageList = document.querySelector('#message-list');
let messageInput = document.querySelector('#msg');
btnSendMsg.addEventListener('click', sendMsgOnclick);
function sendMsgOnclick() {
let message = messageInput.value;
let li = document.createElement('li');
li.appendChild(document.createTextNode('Me: ' + message));
messageList.appendChild(li);
let dataChannels = getDataChannels();
message = username + ': ' + message;
console.log("---------console.log(dataChannels)----------")
console.log(dataChannels)
for (index in dataChannels){
console.log("---------console.log(index)----------")
console.log(index)
dataChannels[index].send(message);
}
messageInput.value = '';
}
function sendSignal(action, message){
let jsonStr = JSON.stringify({
'peer': username,
'action': action,
"message": message,
});
webSocket.send(jsonStr);
}
function createOfferer(peerUsername, receiver_channel_name) {
let peer = new RTCPeerConnection(iceConfiguration);
console.log('=================================')
console.log(peer)
console.log('=================================')
addLocalTracks(peer);
let dc = peer.createDataChannel('channel');
dc.addEventListener('open', () => {
console.log('connection opened!')
})
dc.addEventListener('message', dcOnMessage);
let remoteVideo = createVideo(peerUsername);
setOnTrack(peer, remoteVideo);
mapPeers[peerUsername] = [peer, dc];
peer.addEventListener('iceconnectionstatechange', () => {
let iceConnectionState = peer.iceConnectionState;
if (iceConnectionState === 'failed' || iceConnectionState === 'disconnected' || iceConnectionState === 'closed'){
delete mapPeers[peerUsername];
if (iceConnectionState !== 'closed'){
peer.close();
}
removeVideo(remoteVideo);
}
})
peer.addEventListener('icecandidate', (event) => {
if (event.candidate){
console.log('new ice candidate', JSON.stringify(peer.localDescription))
return;
}
sendSignal('new-offer', {
'sdp': peer.localDescription,
'receiver_channel_name': receiver_channel_name
});
});
peer.createOffer()
.then(o => peer.setLocalDescription(o))
.then(() => {
console.log('Local description set successfully!');
});
}
function createAnswerer(offer, peerUsername, receiver_channel_name) {
let peer = new RTCPeerConnection(iceConfiguration);
console.log('=================================')
console.log(peer)
console.log('=================================')
// let peer = new RTCPeerConnection(null);
addLocalTracks(peer);
let remoteVideo = createVideo(peerUsername);
setOnTrack(peer, remoteVideo);
peer.addEventListener('datachannel', e => {
peer.dc = e.channel;
peer.dc.addEventListener('open', () => {
console.log('connection opened!')
})
peer.dc.addEventListener('message', dcOnMessage);
mapPeers[peerUsername] = [peer, peer.dc];
});
peer.addEventListener('iceconnectionstatechange', () => {
let iceConnectionState = peer.iceConnectionState;
if (iceConnectionState === 'failed' || iceConnectionState === 'disconnected' || iceConnectionState === 'closed'){
delete mapPeers[peerUsername];
if (iceConnectionState !== 'closed'){
peer.close();
}
removeVideo(remoteVideo);
}
})
peer.addEventListener('icecandidate', (event) => {
if (event.candidate){
console.log('new ice candidate', JSON.stringify(peer.localDescription))
return;
}
sendSignal('new-answer', {
'sdp': peer.localDescription,
'receiver_channel_name': receiver_channel_name
});
});
peer.setRemoteDescription(offer)
.then(() => {
console.log('Remote description set successfully for %s.', peerUsername);
return peer.createAnswer();
})
.then(a => {
console.log('Answer created!')
peer.setLocalDescription(a);
})
// peer.createOffer()
// .then(o => peer.setLocalDescription(o))
// .then(() => {
// console.log('Local description set successfully!');
// });
}
function addLocalTracks(peer) {
localStream.getTracks().forEach(track => {
peer.addTrack(track, localStream);
return;
});
}
function dcOnMessage(event) {
let message = event.data;
let li = document.createElement('li')
li.appendChild(document.createTextNode(message));
messageList.appendChild(li);
}
function createVideo(peerUsername) {
let videoContainer = document.querySelector('#video-container');
let remoteVideo = document.createElement('video');
remoteVideo.id = peerUsername + '-video';
remoteVideo.autoplay = true;
remoteVideo.playsInline = true;
let videoWrapper = document.createElement('div');
videoContainer.appendChild(videoWrapper);
videoWrapper.appendChild(remoteVideo);
return remoteVideo;
}
function setOnTrack(peer, remoteVideo) {
let remoteStream = new MediaStream();
remoteVideo.srcObject = remoteStream;
peer.addEventListener('track', async (event) => {
remoteStream.addTrack(event.track, remoteStream);
});
}
function removeVideo(video) {
let videoWrapper = video.parentNode;
videoWrapper.parentNode.removeChild(videoWrapper);
}
function getDataChannels() {
let dataChannels = []
for (peerUsername in mapPeers){
let dataChannel = mapPeers[peerUsername][1];
dataChannels.push(dataChannel);
}
return dataChannels;
}
django channels code in webserver
# Consumer.py
import json
from channels.generic.websocket import AsyncWebsocketConsumer
class ChatConsumer(AsyncWebsocketConsumer):
async def connect(self):
print('connect!!')
self.room_group_name = 'test_room'
await self.channel_layer.group_add(
self.room_group_name,
self.channel_name
)
print(f"room_group_name : {self.room_group_name} and channel_name : {self.channel_name}")
await self.accept()
async def disconnect(self, close_code):
await self.channel_layer.group_discard(
self.room_group_name,
self.channel_name
)
print('disconnected!')
async def receive(self, text_data):
receive_dict = json.loads(text_data)
print(f"receive_data : {receive_dict}")
message = receive_dict['message']
action = receive_dict['action']
if (action == 'new-offer') or (action == 'new-answer'):
receiver_channel_name = receive_dict['message']['receiver_channel_name']
receive_dict['message']['receiver_channel_name'] = self.channel_name
await self.channel_layer.send(
receiver_channel_name,
{
'type': 'send.sdp',
'receive_dict': receive_dict
}
)
return
receive_dict['message']['receiver_channel_name'] = self.channel_name
await self.channel_layer.group_send(
self.room_group_name,
{
'type': 'send.sdp',
'receive_dict': receive_dict
}
)
async def send_sdp(self, event):
print('send_sdp!!')
receive_dict = event['receive_dict']
await self.send(text_data=json.dumps(receive_dict))
# asgi.py
import os
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Project.settings')
django_asgi_app = get_asgi_application()
from channels.auth import AuthMiddlewareStack
import video_app.routing
application = ProtocolTypeRouter({
"http": django_asgi_app,
"websocket": AuthMiddlewareStack(
URLRouter(
video_app.routing.websocket_urlpatterns
)
),
})
#routing.py
from django.urls import re_path
from . import consumers
websocket_urlpatterns = [
re_path(r"^ws/$", consumers.ChatConsumer.as_asgi()),
]
# settings.py
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {
"hosts": [("myredis.cache.amazonaws.com", 6379)]
},
},
}
What is my fault?

JsonWebsocketConsumer class self.send() in a loop sends all the iterations messages at once

when I use self.send(content) in a loop , all the messages are sent at once , instead of one my one.
the first self.send() in the if condition od connecting is executed perfectly
but all loop self.send() messages are recieved by client at once after a delay of about 60 second. how to make it one at a time?
consumer.py
from channels.generic.websockets import JsonWebsocketConsumer
class MyConsumer(JsonWebsocketConsumer):
# Set to True if you want it, else leave it out
strict_ordering = False
def connect(self, message, **kwargs):
super(MyConsumer,self).connect(message)
pass
def receive(self, content, **kwargs):
if content['status'] == "connecting":
content['status'] = "connected"
self.send(content)
elif content['status'] == "data":
for p in range(5):
content={
'status': 'sending',
'polygon': p
}
self.send(content)
time.sleep(15)
self.close()
def disconnect(self, message, **kwargs):
pass
clientside.js
socket = new WebSocket("ws://" + location.host + "/mahaplans/");
socket.onopen = function () {
var msg = {
status: "connecting"
};
socket.send(JSON.stringify(msg))
}
socket.onmessage = function (e) {
let status=JSON.parse(e.data)
if (status["status"]=="connected") {
var imageData={
#someddata
}
socket.send(JSON.stringify(imageData))
}
if (status["status"]=="sending") {
console.log(status["polygon"])
}
}
socket.onclose = function (event) {
console.log("bye bye")
}
if (socket.readyState == WebSocket.OPEN) socket.onopen();

not able to get request,file() working in adonisjs post

when I try to call the request of both the text and the file I don't get a response. postman just show 200 and nothing is updated to the database.
'use strict';
const Pendingupload = use('App/Models/Pendingupload');
const Helpers = use('Helpers');
class UploadController {
async create({ request, response, auth, session }) {
const { title, description } = request.all();
const validationOptions = {
types: ['image'],
size: '2mb',
extnames: ['png', 'gif']
};
// when call it; there is an error
const avatar = request.file('file', validationOptions);
try {
const Pendinguploads = new Pendingupload();
Pendinguploads.title = title;
Pendinguploads.description = description;
Pendinguploads.user_id = await auth.user.id;
Pendinguploads.image_url = '';
// this is when validation occurs
Pendinguploads.image_url = new Date().getTime + '.' + avatar.subtype;
await avatar.move(Helpers.tmpPath('pendinguploads/pic'));
if (!avatar.moved()) {
return avatar.errors();
}
console.log(Pendinguploads.title);
console.log(Pendinguploads.description);
// })
//await request.multipart.process();
await Pendinguploads.save();
session.flash({ message: 'Your video has been posted!.' });
return response.redirect('upload');
} catch (error) {
session.flash({ uploadError: 'could not upload file' + avatar });
return response.redirect('back');
}
}
}
module.exports = UploadController;

cannot create communication from sender to receiver CAF v3

we are able to make communication from sender to receiver.
but we can only send NUMBERS as a custom message ex: 123,45, etc
when we try to attach any string content eg: hello,hello122 or any character the receiver side does not get any message.
We have executed the following code :
try {
const channel = "urn:x-cast:testChannel";
const iframe = document.getElementById("frame");
const node = document.getElementById("message");
const ctx = cast.framework.CastReceiverContext.getInstance();
node.innerHTML = 'test1';
ctx.addCustomMessageListener(channel, (evt) => {
node.innerHTML = 'test...';
ctx.sendCustomMessage('urn:x-cast:testChannel', evt.senderId, 'Message Invoked v3', (data) => {
document.getElementById("message").innerHTML = 'message sent';
iframe.src = "https://duchy-messages.bradnin.ch/";
node.innerHTML = 'Message sent '
})
node.innerHTML = evt.senderId+ ' test ' +JSON.stringify(evt);
alert('here');
})
ctx.start();
} catch (e) {
document.getElementById("message").innerHTML = JSON.stringify(e);
}