Отсоединение веб-сокета CookieCutter Django (с помощью Docker)

Я пытаюсь создать приложение для чата. Я использую Cookiecutter django в качестве инициатора проекта. Использую среду docker и celery, так как мне нужно использовать redis для связи через websocket. Но websocket постоянно разъединяется, даже если я принимаю соединение с потребителями, используя self.accept(). Я также включил CHANNEL_LAYERS в файл config/settings/base.py.

Вот мой локальный env файл.

# General
# ------------------------------------------------------------------------------
USE_DOCKER=yes
IPYTHONDIR=/app/.ipython
# Redis
# ------------------------------------------------------------------------------
REDIS_URL=redis://redis:6379/0
REDIS_HOST=redis
REDIS_PORT=6379

# Celery
# ------------------------------------------------------------------------------

# Flower
CELERY_FLOWER_USER=xxxxx
CELERY_FLOWER_PASSWORD=xxxx

Вот мой consumers.py файл

from channels.generic.websocket import JsonWebsocketConsumer


class ChatConsumer(JsonWebsocketConsumer):
    """
    This consumer is used to show user's online status,
    and send notifications.
    """

    def __init__(self, *args, **kwargs):
        super().__init__(args, kwargs)
        self.room_name = None

    def connect(self):
        print("Connected!")
        self.room_name = "home"
        self.accept()
        self.send_json(
            {
                "type": "welcome_message",
                "message": "Hey there! You've successfully connected!",
            }
        )

    def disconnect(self, code):
        print("Disconnected!")
        return super().disconnect(code)

    def receive_json(self, content, **kwargs):
        print(content)
        return super().receive_json(content, **kwargs)

Вот мой routing.py файл

from django.urls import path
from chat_dj.chats import consumers

websocket_urlpatterns = [
    path('', consumers.ChatConsumer.as_asgi()),
]

Вот мой asgi.py файл

"""
ASGI config

It exposes the ASGI callable as a module-level variable named ``application``.

For more information on this file, see
https://docs.djangoproject.com/en/dev/howto/deployment/asgi/

"""
import os
import sys
from pathlib import Path

from django.core.asgi import get_asgi_application

# This allows easy placement of apps within the interior
# chat_dj directory.

ROOT_DIR = Path(__file__).resolve(strict=True).parent.parent
sys.path.append(str(ROOT_DIR / "chat_dj"))

# If DJANGO_SETTINGS_MODULE is unset, default to the local settings
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.local")

# This application object is used by any ASGI server configured to use this file.
django_application = get_asgi_application()

# Import websocket application here, so apps from django_application are loaded first
from config import routing  # noqa isort:skip

from channels.routing import ProtocolTypeRouter, URLRouter  # noqa isort:skip


application = ProtocolTypeRouter(
    {
        "http": get_asgi_application(),
        "websocket": URLRouter(routing.websocket_urlpatterns),
    }
)

Вот мой local.yml файл

version: '3'

volumes:
  chat_dj_local_postgres_data: {}
  chat_dj_local_postgres_data_backups: {}

services:
  django: &django
    build:
      context: .
      dockerfile: ./compose/local/django/Dockerfile
    image: chat_dj_local_django
    container_name: chat_dj_local_django
    platform: linux/x86_64
    depends_on:
      - postgres
      - redis
    volumes:
      - .:/app:z
    env_file:
      - ./.envs/.local/.django
      - ./.envs/.local/.postgres
    ports:
      - "8000:8000"
    command: /start

  postgres:
    build:
      context: .
      dockerfile: ./compose/production/postgres/Dockerfile
    image: chat_dj_production_postgres
    container_name: chat_dj_local_postgres
    volumes:
      - chat_dj_local_postgres_data:/var/lib/postgresql/data:Z
      - chat_dj_local_postgres_data_backups:/backups:z
    env_file:
      - ./.envs/.local/.postgres

  docs:
    image: chat_dj_local_docs
    container_name: chat_dj_local_docs
    platform: linux/x86_64
    build:
      context: .
      dockerfile: ./compose/local/docs/Dockerfile
    env_file:
      - ./.envs/.local/.django
    volumes:
      - ./docs:/docs:z
      - ./config:/app/config:z
      - ./chat_dj:/app/chat_dj:z
    ports:
      - "9000:9000"
    command: /start-docs

  redis:
    image: redis:6
    container_name: chat_dj_local_redis
    ports:
      - "6379:6379"

  celeryworker:
    <<: *django
    image: chat_dj_local_celeryworker
    container_name: chat_dj_local_celeryworker
    depends_on:
      - redis
      - postgres
    ports: []
    command: /start-celeryworker

  celerybeat:
    <<: *django
    image: chat_dj_local_celerybeat
    container_name: chat_dj_local_celerybeat
    depends_on:
      - redis
      - postgres
    ports: []
    command: /start-celerybeat

  flower:
    <<: *django
    image: chat_dj_local_flower
    container_name: chat_dj_local_flower
    ports:
      - "5555:5555"
    command: /start-flower

Поскольку я использую react в качестве фронтенда, вот моя часть фронтенда, из которой я пытаюсь подключиться к websocket.

import React from 'react';
import useWebSocket, { ReadyState } from 'react-use-websocket';

export default function App() {
  const { readyState } = useWebSocket('ws://127.0.0.1:8000/', {
    onOpen: () => {
      console.log("Connected!")
    },
    onClose: () => {
      console.log("Disconnected!")
    }
  });

  const connectionStatus = {
    [ReadyState.CONNECTING]: 'Connecting',
    [ReadyState.OPEN]: 'Open',
    [ReadyState.CLOSING]: 'Closing',
    [ReadyState.CLOSED]: 'Closed',
    [ReadyState.UNINSTANTIATED]: 'Uninstantiated',
  }[readyState];

  return (
    <div>
      <span>The WebSocket is currently {connectionStatus}</span>
    </div>
  );
};

Websocket постоянно отключается, и я не знаю почему. Поскольку я использую машину windows, локально я не могу использовать redis, и я не знаю, что не так с cookiecutter django.

Вернуться на верх