# Django channels not sending message on heroku live server

**URL:** <https://forum.djangoproject.com/t/django-channels-not-sending-message-on-heroku-live-server/22008>\
**Category:** Forms & APIs\
**Created:** [July 1, 2023, 7:49pm UTC](https://forum.djangoproject.com/t/django-channels-not-sending-message-on-heroku-live-server/22008 "2023-07-01T19:49:37Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![desphixs](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/desphixs/32/6411_2.png) [@desphixs](https://forum.djangoproject.com/u/desphixs)\
**Post date:** [July 1, 2023, 7:49pm UTC](https://forum.djangoproject.com/t/django-channels-not-sending-message-on-heroku-live-server/22008/1 "2023-07-01T19:49:37Z")

</div>

To send messages in real time, I have configured Django, channels, Redis, and Daphne. When it is being developed, it functions exactly as planned, but as soon as it is deployed to the live server, it stops functioning. The problem is that, contrary to my expectations, when I type a message in the input field and click the submit button, the page reloads. I’m not sure if the messages are actually transmitted or not when the page reloads, but because my database does not save the messages, I assume they are not.

I have preventDefault() in the javascript, or is there something else to do while on a live server?  
This is the script that makes the call to the channels

```auto
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
    $(function () {
        var receiver = null;
        var receiver_id = "{{ reciever.username }}";
        var logged_in = "{{ request.user.username }}";
        const pathname = window.location.pathname;

        const parts = pathname.split("/");
        const username = parts[parts.length - 2];

        if (receiver_id === logged_in) {
            receiver = receiver_id;
        } else {
            receiver = receiver_id;
        }

        var socket = new WebSocket("ws://" + window.location.host + "/ws/chat/" + receiver + "/");

        socket.onopen = function () {
            console.log("WebSocket connection established.");
        };

        var typingTimer;
        var typingTimeout = 1000;

        $("#chat-input").on("input", function () {
            clearTimeout(typingTimer);

            typingTimer = setTimeout(function () {
                $("#typing-status").text("");
            }, typingTimeout);

            $("#typing-status").text("typing...");
        });

        socket.onmessage = function (event) {
            var data = JSON.parse(event.data);
            var message = data.message;
            var sender = data.sender;
            var profileImage = data.profile_image;
            var reciever = data.reciever;
            var typing = data.typing;

            if (sender === "{{sender}}") {
                var chatMessage = '<div class="d-flex flex-row justify-content-end message">';
                chatMessage += '<div style="margin-left: 20px;">';
                chatMessage += '<p class="small p-2 me-3 mb-1 text-white rounded-3 custom-bg">' + message + "</p>";
                chatMessage += '<p class="small me-3 mb-3 rounded-3 text-muted">0 minute ago</p>';
                chatMessage += "</div>";
                chatMessage += '<img style="width: 50px; height: 50px; object-fit: cover; border-radius: 50%; " src="' + profileImage + '" class="">';
                chatMessage += "</div>";
                $("#chat-messages").append(chatMessage);
                var chatContainer = document.querySelector(".chat_container");
                chatContainer.scrollTop = chatContainer.scrollHeight;
                console.log("Yes");
            } else {
                var chatMessage = '<div class="d-flex flex-row justify-content-start message">';
                chatMessage += '<img style="width: 50px; height: 50px; object-fit: cover; border-radius: 50%;" src="' + profileImage + '" class="">';
                chatMessage += '<div style=" padding-left: 13px;" >';
                chatMessage += '<p class="small p-2 me-3 mb-1 rounded-3" style="background-color: #f5f6f7;">' + message + "</p>";
                chatMessage += '<p class="small me-3 mb-3 rounded-3 text-muted">0 minute ago</p>';
                chatMessage += "</div>";
                chatMessage += "</div>";
                $("#chat-messages").append(chatMessage);
                var chatContainer = document.querySelector(".chat_container");
                chatContainer.scrollTop = chatContainer.scrollHeight;
                console.log("No");
            }

            if (typing && sender !== logged_in) {
                $("#typing-status").text("typing...");
            } else {
                $("#typing-status").text("");
            }
        };

        socket.onclose = function () {
            console.log("WebSocket connection closed.");
        };

        $("#chat-send").on("submit", function (e) {
            e.preventDefault();
            var input = $("#chat-input");
            var message = input.val();
            var sender = "{{request.user.username}}";
            var data = {
                message: message,
                sender: sender,
                reciever: username,
                typing: false,
            };
            socket.send(JSON.stringify(data));
            input.val("");
            var $proceedButton = $("#proceed-btn");
            $proceedButton.prop("disabled", true);
            $(".chat_container").scrollTop(100000000000);
            $("#message-form")[0].reset();
        });
    });

    $(document).ready(function () {
        $(".chat_container").scrollTop(100000000000);
        $("#message-form").preventDefault();
    });
</script>

```

### **Do I need to display more files, such as routing.py, settings.py, or consumer.py?**

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [July 1, 2023, 10:59pm UTC](https://forum.djangoproject.com/t/django-channels-not-sending-message-on-heroku-live-server/22008/2 "2023-07-01T22:59:10Z")

</div>

Your browser’s developer tools on the network tab is very useful for showing you the requests and responses. You can use it to see if you’re sending messages through the websocket or not.

In general, the situation you’re describing occurs when someone isn’t logged on when the websocket is being opened. (There are _many_ reasons why this might be happening - that’s just one reason that I see frequently around here because people tend to open the websocket on the home page.)

I don’t know heroku, so unfortunately I’m not going to be able to provide you with any specific advice in that area, but I do notice a couple things you might want to think about changing.

First, there’s no need to define your button as a `submit` button. You can define it as a `button` and capture the `click` event for that button. That prevents the browser from even trying to submit the form as a regular post and avoids the need for calling `preventDefault`.

Second, these are apparently users that are logged on, which makes these lines in your JavaScript unnecessary:

> [@desphixs](#):
>
> ` var sender = "{{request.user.username}}";`

and

> [@desphixs](#):
>
> ` sender: sender,`

The scope in the consumer contains the user associated with that socket, giving you a secure method of identifying the sender. (Your method doesn’t prevent someone from changing that variable and impersonating someone else.)

Along with the information above, this is very insecure:

> [@desphixs](#):
>
> ```auto
> var receiver_id = "{{ reciever.username }}";
> var logged_in = "{{ request.user.username }}";
> 
> ```

You have absolutely no protection against impersonation here. These types of settings and protections should be handled by the server in the consumer. You want to become more familiar with the scope and the features available in the consumer.

---

<div class="post-metadata">

**Author:** ![desphixs](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/desphixs/32/6411_2.png) [@desphixs](https://forum.djangoproject.com/u/desphixs)\
**Post date:** [July 4, 2023, 6:57pm UTC](https://forum.djangoproject.com/t/django-channels-not-sending-message-on-heroku-live-server/22008/3 "2023-07-04T18:57:18Z")

</div>

Thank you very much for your response.

> [@Ken Whitesell](#):
>
> Your browser’s developer tools on the network tab are very useful for showing you the requests and responses. You can use it to see if you’re sending messages through the web socket or not.

With the help of the developer tool, i found some errors that helped me fix the issues

> [@Ken Whitesell](#):
>
> First, there’s no need to define your button as a `submit` button. You can define it as a `button` and capture the `click` event for that button. That prevents the browser from even trying to submit the form as a regular post and avoids the need for calling `preventDefault`.

This also stopped the page from reloading, and in the scripts, i had to change ws" to **wss** ` var socket = new WebSocket("ws://" ...") ;` to `var socket = new WebSocket("wss://" ...") ;`

What I am still trying to figure out is how to prevent impersonation, just like you said. I’d really appreciate some guidance on how to do that, as right now I do not really know what to do about it.

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [July 4, 2023, 7:25pm UTC](https://forum.djangoproject.com/t/django-channels-not-sending-message-on-heroku-live-server/22008/4 "2023-07-04T19:25:29Z")

</div>

> [@desphixs](#):
>
> What I am still trying to figure out is how to prevent impersonation, just like you said.

When a person logs on before opening the websocket, the consumer creates [the scope object](https://channels.readthedocs.io/en/stable/topics/consumers.html#scope) which is available within the consumer. You don’t need to trust the browser to send in the current user, the consumer has it directly.

---

<div class="post-metadata">

**Author:** ![desphixs](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/desphixs/32/6411_2.png) [@desphixs](https://forum.djangoproject.com/u/desphixs)\
**Post date:** [July 5, 2023, 12:17pm UTC](https://forum.djangoproject.com/t/django-channels-not-sending-message-on-heroku-live-server/22008/5 "2023-07-05T12:17:56Z")

</div>

Now I understand, just to be sure: I can use `scope["user"]` on the consumer side if I configure authentication in the channel rather than doing `let user = "{{ request.user }}"` on the client side, am I right?

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [July 5, 2023, 12:28pm UTC](https://forum.djangoproject.com/t/django-channels-not-sending-message-on-heroku-live-server/22008/6 "2023-07-05T12:28:28Z")

</div>

> [@desphixs](#):
>
> …I configure authentication in the channel…

I don’t know what you mean by that.

My authentication occurs within Django, not Channels.

I don’t open the websocket until _after_ the user has logged in.

At that point, Channels will have created the scope with the reference to the logged-in user.

If the websocket is opened before the user has logged in, then the scope can’t be created with a user.

---

<div class="post-metadata">

**Author:** ![desphixs](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/desphixs/32/6411_2.png) [@desphixs](https://forum.djangoproject.com/u/desphixs)\
**Post date:** [July 20, 2023, 9:04am UTC](https://forum.djangoproject.com/t/django-channels-not-sending-message-on-heroku-live-server/22008/7 "2023-07-20T09:04:21Z")

</div>

> [@Ken Whitesell](#):
>
> I don’t open the websocket until after the user has logged in.
> 
> At that point, Channels will have created the scope with a reference to the logged-in user.
> 
> If the websocket is opened before the user has logged in, then the scope can’t be created with a user.

Thanks a lot; using this, I have fixed the issue.
