I am having a heck of a time getting a notification from Django-postman to a websocket so the other user will know when a message has arrived. I have tried numerous attempts and still am having issues. My websocket is running but I cannot get the message to appear. Any help would be appreciated
If you would like assistance with this, we’ll need to see the relevant code. It would also help if you provided a description of how you’re intending this to work (technically).
thanks…i am fairly new to this, so if you will bear with me. What parts of the code do you need to see?
My overall project is a multi-app, one of which is Django-Postman. as you know it is a simple in-app project. What i am attempting to have happen, is when one of my users sends a message from the postman app, the receiver gets a toast-like message on screen, showing a simply message like “bob sent a message” or “harry replied to your message”. My entire project is on a closed intranet, with extremely limited access… so i am having to develop this and switch back and forth between networks…
The initial code we’d need to see then is whatever code you’ve written that, when you send a message through Django-postman, also sends a message to the channels layer to provide this notification.
this is from my views.py:
channel_layer = get_channel_layer()
def send_notification(message):
# This will print the message to the console
print(f"Sending message: {message}")
# This will send the message to the client.
async_to_sync(channel_layer.send)('notifications', {
'type': 'notification.message',
'message': message
})
here is my consumers.py
import json
from channels.generic.websocket import AsyncWebsocketConsumer
class NotificationConsumer(AsyncWebsocketConsumer):
async def connect(self):
await self.accept()
async def disconnect(self, close_code):
pass
async def receive(self, text_data):
text_data_json = json.loads(text_data)
message = text_data_json['message']
await self.send(text_data=json.dumps({
'message': message
}))
and the script from base.html for starting the websocket:
<script>
var socket = new WebSocket('ws://localhost:8600/ws/notifications/');
socket.onmessage = function(event) {
var data = JSON.parse(event.data);
console.log('Received message:', message);
};
socket.onopen = function(event) {
console.log('WebSocket connection opened.');
};
socket.onclose = function(event) {
console.log('WebSocket connection closed.');
};
</script>
This is attempting to send to a channel named “notifications”.
Unless you have a worker process associated with that name, there’s no place to deliver the message to.
If you’re looking to send a message to a specific user, you need to “locate” that user.
The method that I use, is that every user logging on joins a group named user_<username>
. (e.g. user_ken
).
Any other channels client can send a message to me by sending a message to the group user_ken
.
Example from what you have above:
def send_notification(message):
# This will print the message to the console
print(f"Sending message: {message}")
# assume that the target username is in `message.username`
group_name = f'user_{message.username}'
# This will send the message to the client.
async_to_sync(channel_layer.group_send)(group_name, {
'type': 'notification.message',
'message': message
})
Otherwise, you would need to know the precise channel name for that user in order to direct the message to that user.
So how would i setup what your describing? my friends call me a ducktape programmer and it is bearing true!! Thanks for helping… i can see some of what your describing but i do not understand how to set the channel_layer_group.
Your consumer would have each connecting user create their group. See the docs at Channel Layers — Channels 4.0.0 documentation.
In this particular case, each user, when they connect their websocket, would be joining their individual group.
will so what i can… before i go, from your experience, is there a better way of doing what i am attempting with Django-postman? if so i may need to go down that trail. Again thanks
Sorry, I’ve never used Django-postman and have never had the need for the type of messaging it supports.
Side note: You’ve a case where you have the ``` on the same line as some other text - I’ve fixed that for you.
You need to go back and reread my previous reply at integrating Django-postman - #6 by KenWhitesell
Every browser is connected to its own instance of a consumer. It’s not like there are multiple connections sharing the same consumer instance.
Sending messages between users requires that the message be passed from the consumer for the originating source, through the channel layer, to the consumer for the destination, where it can then be sent out to the browser. This means that the originating consumer needs to know a channel that the destination consumer is listening to - and that’s where the “one-person group” comes in to play.