Skip to content

Commit

Permalink
Improve sockets
Browse files Browse the repository at this point in the history
  • Loading branch information
princekhunt committed May 4, 2024
1 parent 136665f commit 3b1c461
Show file tree
Hide file tree
Showing 5 changed files with 324 additions and 241 deletions.
24 changes: 13 additions & 11 deletions assets/js/chat/Base.js
Original file line number Diff line number Diff line change
Expand Up @@ -188,20 +188,22 @@ function delete_friend(friend){
},
success: function(response){
if(response.status == true){
Swal.fire(
'Deleted!',
'User has been deleted.',
'success'
).then(function(){
location.reload();
Swal.fire({
title: 'Deleted!',
text: 'User has been deleted.',
confirmButtonColor: '#3085d6',
icon: 'success',
}).then(function(){
parent.location.href = '/';
});
}
else{
Swal.fire(
'Error!',
'An error occured. Please try again later.',
'error'
);
Swal.fire({
title: 'Error!',
text: 'An error occured. Please try again later.',
confirmButtonColor: '#3085d6',
icon: 'error',
});
}
},
error: function(response){
Expand Down
14 changes: 7 additions & 7 deletions assets/js/chat/chats.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
const socketProtocol3 = (window.location.protocol === 'https:') ? 'wss' : 'ws';
const socketProtocol_3 = (window.location.protocol === 'https:') ? 'wss' : 'ws';

const socket3 = new WebSocket(socketProtocol3 + "://" + window.location.host + '/ws/chat');
socket3.onopen = function (e) {
socket3.send(JSON.stringify({
const socket_3 = new WebSocket(socketProtocol_3 + "://" + window.location.host + '/ws/chat/status/');
socket_3.onopen = function (e) {
socket_3.send(JSON.stringify({
'check': 'livestatus',
'for': getUserName(),
}));
};

//keep checking if user is online
setInterval(function () {
socket3.send(JSON.stringify({
socket_3.send(JSON.stringify({
'check': 'livestatus',
'for': getUserName(),
}));
}, 3000);

var count = 0;
socket3.addEventListener('message', function (e) {
socket_3.addEventListener('message', function (e) {
const data = JSON.parse(e.data);
if (data.status == 'offline') {
if (count >= 3) {
Expand All @@ -28,7 +28,7 @@ socket3.addEventListener('message', function (e) {
text: "User disconnected, Navigating you to home page!",
}).then(function(){
parent.location.href = "/";

});
}
else {
Expand Down
230 changes: 112 additions & 118 deletions chat/consumers.py
Original file line number Diff line number Diff line change
@@ -1,145 +1,104 @@
import json
from json.decoder import JSONDecodeError
from channels.generic.websocket import AsyncJsonWebsocketConsumer
from channels.generic.websocket import WebsocketConsumer
from asgiref.sync import async_to_sync
from chat.models import Keys, UserProfile
from channels.db import database_sync_to_async
import time
from chat.models import UserProfile

class ChatConsumer(WebsocketConsumer):


"""
Description: This consumer is used to send and receive messages between two users.
A user will send a message ('message') along with the username ('to') of friend to send the message to the friend, also the user will send a message ('destroy') to destroy the message.
'destroy' contains seconds after which the message will be destroyed.
If the friend is online, the message will be sent to the friend and the user will receive a message with status 'received'.
"""
http_user_and_session = True
def connect(self):
user = self.scope["user"]

UpdateStatus = UserProfile.objects.get(username=user)
UpdateStatus.online = 1

UpdateStatus.save()

self.room_name = "box_"+str(user)

async_to_sync(self.channel_layer.group_add)(
self.room_name,
self.channel_name
)
self.accept()

def receive(self, text_data=None, bytes_data=None):
text_data_json = json.loads(text_data)
message = text_data_json['message']
to = text_data_json['to']
destroy = text_data_json['destroy']

if message == "ping":
self.send(text_data=json.dumps({
'message': "pong",
'status': "received",
'destroy': destroy
}))
return

async_to_sync(self.channel_layer.group_send)(
"box_"+str(to),
{
'type': 'chat_message',
'message': message,
'destroy': destroy
}
)

def receive(self, text_data=None, bytes_data=None):
text_data_json = json.dumps(text_data)
text_data_json = json.loads(text_data)
def chat_message(self, event):
self.send(text_data=json.dumps({
'message': event['message'],
'status': "received",
'destroy': event['destroy']
}))

try:
#Check User's online status
if text_data_json['check']=="livestatus":
ForUser = text_data_json['for']
user = self.scope["user"]
#requested user's userprofile
if UserProfile.objects.get(username=ForUser).online==1 and UserProfile.objects.get(username=ForUser).online_for==UserProfile.objects.get(username=user):
async_to_sync(self.channel_layer.group_send)(
"box_"+str(ForUser),
{
'type': 'UserLiveStatus',
'status': 'online',
'user': ForUser
}
)
else:
self.send(text_data=json.dumps({
'status': "offline",
'user': ForUser
}))

except Exception as e:
pass


try:
if text_data_json['status'] == "online" and text_data_json['for']!="NULL":
ForUser = text_data_json['for']
user = self.scope["user"]
UserUpdate = UserProfile.objects.get(username=user)
UserUpdate.online_for = UserProfile.objects.get(username=ForUser)
UserUpdate.save()
#end here
except Exception as e:
pass

try:
if text_data_json['status'] == "typing" and text_data_json['for']!="NULL":
ForUser = text_data_json['for']
user = self.scope["user"]

async_to_sync(self.channel_layer.group_send)(
"box_"+str(ForUser),
{
'type': 'In_chat_message',
'status': 'typing',
'user': ForUser
}
)
except Exception as e:
pass

try:
message = text_data_json['message']
to = text_data_json['to']
destroy = text_data_json['destroy']

def disconnect(self, code):
user = self.scope["user"]
UpdateStatus = UserProfile.objects.get(username=user)
UpdateStatus.online = 0
UpdateStatus.online_for = None
UpdateStatus.save()
self.close()

async_to_sync(self.channel_layer.group_send)(
"box_"+str(to),
{
'type': 'chat_message',
'message': message,
'destroy': destroy
}
)

except Exception as e:
pass
class ChatConsumerStatus(WebsocketConsumer):
"""
Description: This consumer is used to check the online status of the user.
A user will send a message ('check') along with the username ('for') of friend to check the online status of the friend.
If the friend is online, the user will receive a message with status 'online' and vice versa.
"""
http_user_and_session = True
def connect(self):
user = self.scope["user"]
self.room_name = "box2_"+str(user)
async_to_sync(self.channel_layer.group_add)(
self.room_name,
self.channel_name
)
self.accept()

def receive(self, text_data=None, bytes_data=None):
text_data_json = json.loads(text_data)

try:
if text_data_json['status'] == "online" and text_data_json['for']!="NULL":
ForUser = text_data_json['for']
user = self.scope["user"]

if text_data_json['check']=="livestatus":
ForUser = text_data_json['for']
user = self.scope["user"]
if UserProfile.objects.get(username=ForUser).online==1 and UserProfile.objects.get(username=ForUser).online_for==UserProfile.objects.get(username=user):
async_to_sync(self.channel_layer.group_send)(
"box_"+str(ForUser),
"box2_"+str(ForUser),
{
'type': 'In_chat_message',
'type': 'UserLiveStatus',
'status': 'online',
'user': ForUser
}
)
except Exception as e:
pass

def chat_message(self, event):
print(event['destroy'])
try:
self.send(text_data=json.dumps({
'message': event['message'],
'status': "received",
'destroy': event['destroy']
}))
except:
pass

def In_chat_message(self, event):

type = event['type']
status = event['status']
user = event['user']
self.send(text_data=json.dumps({
'status': status,
'user': user
}))
else:
self.send(text_data=json.dumps({
'status': 'offline',
'user': ForUser
}))

def UserLiveStatus(self, event):
status = event['status']
Expand All @@ -150,17 +109,52 @@ def UserLiveStatus(self, event):
}))

def disconnect(self, code):
self.close()

class ChatConsumerCurrentStatus(WebsocketConsumer):
"""
Description: This consumer is used to check the current status of the user (typing/not typing).
A user will send a message ('status') along with the username ('for') of friend to check the current status of the friend.
If the friend is typing, the user will receive a message with status 'typing' otherwise 'online'.
"""
http_user_and_session = True
def connect(self):
user = self.scope["user"]
try:
self.room_name = "box3_"+str(user)
async_to_sync(self.channel_layer.group_add)(
self.room_name,
self.channel_name
)
self.accept()

UpdateStatus = UserProfile.objects.get(username=user)
UpdateStatus.online = 0

UpdateStatus.online_for = None
def receive(self, text_data=None, bytes_data=None):
text_data_json = json.loads(text_data)

if text_data_json['for'] != "NULL":
status = text_data_json['status']
ForUser = text_data_json['for']
user = self.scope["user"]
UserUpdate = UserProfile.objects.get(username=user)
UserUpdate.online_for = UserProfile.objects.get(username=ForUser)
UserUpdate.save()

UpdateStatus.save()
async_to_sync(self.channel_layer.group_send)(
"box3_"+str(ForUser),
{
'type': 'In_chat_message',
'status': status,
'user': ForUser
}
)

except:
pass
def In_chat_message(self, event):
status = event['status']
user = event['user']
self.send(text_data=json.dumps({
'status': status,
'user': user
}))

pass
def disconnect(self, code):
self.close()
6 changes: 4 additions & 2 deletions chat/routing.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from django.urls import re_path as url
from chat.consumers import ChatConsumer
from chat.consumers import ChatConsumer, ChatConsumerStatus, ChatConsumerCurrentStatus

websocket_urlpatterns = [
url('ws/chat', ChatConsumer.as_asgi())
url('ws/chat/currentstatus/', ChatConsumerCurrentStatus.as_asgi()),
url('ws/chat/status/', ChatConsumerStatus.as_asgi()),
url('ws/chat/', ChatConsumer.as_asgi()),
]
Loading

0 comments on commit 3b1c461

Please sign in to comment.