Having problem sending data between 2 scope classes in Django Channels
I am using django channels for the first time and can't wrap my head around something. Here is what I am trying to achieve; I want to create a new message in ChatConsumer which is all good and fine. Problem occurs when i try to pass the id of the chat that new message was created in. I don't get any errors or feedback or nothing. It just fails silently.
Here is the code base
class ChatConsumer(WebsocketConsumer):
"""
On initial request, validate user before allowing connection to be accepted
"""
#on intial request
def connect(self):
self.room_name = self.scope['url_route']['kwargs']['room_name']
self.room_group_name = f'chat_{self.room_name}'
async_to_sync(self.channel_layer.group_add)(
self.room_group_name,
self.channel_name
)
# accept connection
self.accept()
# send response
self.send(text_data=json.dumps({
'type':'connection_established',
'message':'You are connected'
}))
def receive(self, text_data):
# get data sent from front end
text_data_json = json.loads(text_data)
# message
message = str(text_data_json['form']['message'])
if message.strip() == "":
message = None
# try to decode image or set to none if not available
try:
base64_image = text_data_json['form']['image']
if base64_image.startswith('data:image'):
base64_image = base64_image.split(';base64,')[1]
img_name = random.randint(1111111111111,999999999999999)
data = ContentFile(base64.b64decode(base64_image), name= 'image' + str(img_name) + '.jpg')
except AttributeError:
data = None
# send message
sender = self.scope['user']
# extract chat ID
chat_id = int(self.scope['url_route']['kwargs']['room_name'])
try:
_chat = Chat.objects.get(id = chat_id)
except Chat.DoesNotExist:
self.close()
_requesting_user = self.scope['user']
# make sure user is in the conversation before attempting to create message
if _chat.user_1 == _requesting_user.id or _chat.user_2 == _requesting_user.id:
# get host address from header dictionary
base = self.scope['headers']
host = ''
for _ in base:
if _[0] == b'origin':
host = _[1].decode('utf-8')
break
chat_user = ChatUser.objects.get(user = sender)
# if message is valid, create.
if message != None or data != None:
new_message = Message.objects.create(message = message, chat = _chat, user = chat_user, media = data)
# boradcast chat id to chat list consumer of other user after creation
#get receiver id
if sender.id == _chat.user_1:
receiver_id = int(_chat.user_2)
else:
receiver_id = int(_chat.user_1)
receiver = f'user_{sender.id}'
# send message to that user consumer... CODE DOESN'T SEND ANYTHING BUT PROGRAMS PROCECEED SUCCESSFULLY
async_to_sync(self.channel_layer.group_send(
f"user_{receiver_id}",
{
'type':'new_message_signal',
'chat_id' : _chat.id
}
))
_serialized_data = _serialize_message(user = _requesting_user, base = host, message= new_message)
# set up alert both users of new message
_chat.user_1_has_read = False
_chat.user_2_has_read = False
_chat.save()
# broadcast to group
async_to_sync(self.channel_layer.group_send)(
self.room_group_name,
{
'type':'chat_message',
'message' : _serialized_data
}
)
def chat_message(self, event):
message = event['message']
# get user to check if message being broadcast to them was sent by them
user = self.scope['user']
chat_user = ChatUser.objects.get(user = user)
if chat_user.id != message['user']:
message['from'] = True
else:
message['from'] = False
# get chat to mark all users currently in connection as read
chat = Chat.objects.get(id = int(message['chat']))
if user.id == chat.user_1:
chat.user_1_has_read = True
if user.id == chat.user_2:
chat.user_2_has_read = True
chat.save()
# send response
self.send(json.dumps({
'type':'new_message',
'message' : message
}))
Here is the ChatListConsumer instance meant to receive and handle it
class ChatListConsumer(WebsocketConsumer):
def connect(self):
user = self.scope['user'] # get user on start of connection
self.room_group_name = f"user_{user.id}" # add each user to their own group while they're online
async_to_sync(self.channel_layer.group_add)(
self.room_group_name,
self.channel_name
) # add group
self.accept()
print(self.room_group_name)
self.send(text_data=json.dumps({
'type' : 'connected',
'message':'You have been connected'
}))
def receive(self, text_data):
data = json.loads(text_data)
print(data)
def new_message_signal(self, event): # receive signal from other consumer
print(event)
chat_id = event['chat_id'] # id of chat to send back to front-end
print(f"Chat is of new chat is {chat_id}.")# nothing happens
Nothing happens. Both channels work indivdually. I can send to and from both the chat and the global sockets individually. Just when i try to pass from chat to global afterwards, it fails silently.