如何在生产Pythonanywhere中运行WebSocket(django-channels)?

vpfxa7rd  于 2023-06-25  发布在  Go
关注(0)|答案(2)|浏览(107)

在遵循官方Django-channels教程之后,我使用WebSockets创建了一个简单的聊天应用程序。但是,我不能让它在生产中工作。我做了一些谷歌搜索,发现一个论坛在Python的任何地方说,他们不支持WebSocket,我联系了团队,他们告诉我同样的事情。我做了更多的谷歌搜索,找到了与达芙妮服务器,Nginx相关的东西,还有其他一些我以前从未听说过的东西。
由于我是Django频道的新手,我现在非常困惑!有没有什么我可以做的,使我的WebSocket网站正常运行在Pythonanywhere的生产(当然是免费的)或者我必须删除所有的WebSocket代码,并取代它与重复的Http调用检查新的消息(与 AJAX )?
如果没有其他解决方案,只能移动到重复的Http调用,是否有任何其他的网络托管服务,提供免费的游戏,其中包括免费的SSL认证,域名(如mydomain.servicename.com),而不是随机字符,和WebSocket支持?
谢谢

我使用的代码

我不知道它是否相关,而且它在开发中运行得很好,所以我不认为它有错误
settings.py:

INSTALLED_APPS = [
    'channels',
    ...
    'django_cleanup',
]

ASGI_APPLICATION = 'orgachat.routing.application'

CHANNEL_LAYERS = {
    'default': {
        'BACKEND': 'channels_redis.core.RedisChannelLayer',
        'CONFIG': {
            "hosts": [('127.0.0.1', 6379)],
        },
    },
}

main routing.py(在路由文件夹中)

from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
from chat.routing import websocket_urlpatterns as chat_routing

application = ProtocolTypeRouter({
    "websocket": AuthMiddlewareStack(
        URLRouter(
            chat_routing,
        )
    )
})

routing.py for chat app

from django.urls import path
from . import consumers

websocket_urlpatterns = [
    path('ws/chat/room/<int:room_id>/', consumers.RoomConsumer),
]

consumers.py

import json
from channels.generic.websocket import AsyncWebsocketConsumer

class RoomConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        self.group_name = str(self.scope['url_route']['kwargs']['room_id'])
        await self.channel_layer.group_add(self.group_name, self.channel_name)
        await self.accept()

    async def disconnect(self, code):
        await self.channel_layer.group_discard(self.group_name, self.channel_layer)

    async def receive(self, text_data):
        message_json = json.loads(text_data)
        await self.channel_layer.group_send(self.group_name, {
            'type': 'send_message',
            'content': message_json['content'],
            'area': message_json['area'],
            'area_id': message_json['area_id'],
            'username': self.scope['user'].username,

        })

    async def send_message(self, event):
        await self.send(json.dumps(event))

完整的JS脚本

<script>
        // -------------------
        // WEBSOCKET SETUP
        // -------------------
        var wsStart = 'ws://'
        var hostName = window.location.hostname + ':8000'
        if (window.location.protocol.includes('https')) {
            wsStart = 'wss://'
            hostName = window.location.hostname
        };
        let endpoint = wsStart + hostName + '/ws' + window.location.pathname
        console.log(endpoint)
        var socket = new WebSocket(endpoint);

        socket.onmessage = function (e) {
            // todo not show message if in a different room
            data = JSON.parse(e.data);
            console.log(data.area_id)
            console.log(data.area)
            var sender = 'other'
            var username = data.username
            if (data.username == "{{ user.username }}") {
                sender = 'self';
                username = 'You'
            }
            document.querySelector('.messages').innerHTML += `
            <div class="message ${sender}">
            <p>${username} &mdash; ${data.area}:</p>
            <p>${data.content}</p>
        </div>
            `
            document.querySelector('#notification_sound').play()
        }
        socket.onerror = function (e) {
            alert("SERVER ERROR 500, You won't be able to see messages unless you refresh,")
        }
        socket.onclose = function (e) {}

        document.addEventListener('DOMContentLoaded', function () {
            document.querySelector('#sendMessage').onclick = function (e) {
                e.preventDefault();
                // ------------AJAX: SEND AND MESSAGE---------------
                let xhr = new XMLHttpRequest();
                xhr.onreadystatechange = function (e) {
                    if (this.readyState == 4 && this.status == 200) {
                        document.querySelector('#id_content').value = '';
                    }
                }
                xhr.open("POST", "{% url 'chat:room' room.id %}", true);
                xhr.setRequestHeader('Content-type', "application/x-www-form-urlencoded");
                data = {
                    'csrfmiddlewaretoken': '{{ csrf_token }}',
                    'content': document.querySelector('#id_content').value,
                    'area': parseInt(document.querySelector('#id_area').value),
                }
                xhr.send(JSON.stringify(data));

                // ---------------WEBSOCKET: ECHO MESSAGE---------------
                let area = document.getElementById('id_area')
                socket.send(JSON.stringify({
                    'content': document.querySelector('#id_content').value,
                    'area': area.options[area.selectedIndex].text,
                    'area_id': document.querySelector('#id_area').value
                }));
            }
        });
    </script>
q0qdq0h2

q0qdq0h21#

Websockets和django-channels在PythonAnywhere上不受支持。

velaa5lx

velaa5lx2#

你可以试着运行免费的云计算机,比如GCP,并在那里托管你的项目
有许多免费的云计算,你可以尝试,看看事情是如何进行的

相关问题