Конфигурация Heroku, daphne, redis - КАНАЛЫ
Я пытаюсь заставить каналы django работать с daphne, очевидно, что daphne (PROCFILE) работает и redis (часть CHANNEL_LAYERS) тоже, но я не могу подключиться, всякий раз, когда я запускаю приложение и открываю "комнату", оно автоматически отключается, стоит упомянуть, что мой сайт работает с HTTPS и имеет действующий сертификат
У меня есть
Django==4.0.6
daphne==3.0.2
channels==3.0.5
Мои конфигурации
ASGI.PY
import os
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.security.websocket import AllowedHostsOriginValidator
from django.core.asgi import get_asgi_application
from django.urls import path
import django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myProject.settings")
# Initialize Django ASGI application early to ensure the AppRegistry
# is populated before importing code that may import ORM models.
django.setup()
django_asgi_app = get_asgi_application()
from chat import consumers
application = ProtocolTypeRouter({
# Django's ASGI application to handle traditional HTTP requests
"http": django_asgi_app,
# WebSocket chat handler
"websocket": AllowedHostsOriginValidator(
AuthMiddlewareStack(
URLRouter([
path("ws/<str:room_name>/", consumers.ChatConsumer.as_asgi()),
])
)
),
})
ПРОКФИЛЬ (работает Дафна)
web: daphne myProject.asgi:application --port $PORT --bind 0.0.0.0 -v2
web2: gunicorn myProject.wsgi --log-file -
worker: python manage.py runworker channel_layer -v2
НАСТРОЙКИ
....
ASGI_APPLICATION = 'myProject.asgi.application'
# Channels
CHANNEL_LAYERS = {
"default": {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
"CONFIG": {
"hosts": ["redis://:XXXXXXXXXXXeca8e639d8b1ca9617d708224c89641133e6191292a@XXXXXXXXX-25-163.compute-1.amazonaws.com:27320"]
},
},
}
....
CONSUMERS.PY
import json
from channels.generic.websocket import AsyncWebsocketConsumer
from asgiref.sync import sync_to_async
from django.contrib.auth.models import User
from .models import Message, Room
class ChatConsumer(AsyncWebsocketConsumer):
async def connect(self):
self.room_name = self.scope['url_route']['kwargs']['room_name'] # url route {'args': (), 'kwargs': {'room_name': 'Yoru Room Name'}}
self.room_group_name = 'chat_%s' % self.room_name #chat_my_room
await self.channel_layer.group_add(
self.room_group_name, # group
self.channel_name # channel
)
await self.accept()
async def disconnect(self, close_code):
await self.channel_layer.group_discard(
self.room_group_name, # group
self.channel_name # channel
)
async def receive(self, text_data):
data = json.loads(text_data) # load json package {"message":"","username":"","room":""}
message = data['message']
username = data['username']
room = data['room']
await self.save_message(username, room, message)
await self.channel_layer.group_send(
self.room_group_name,
{
'type' : 'chat_message',
'message' : message,
'username' : username,
'room' : room,
}
)
async def chat_message(self, event):
message = event['message']
username = event['username']
room = event['room']
await self.send(text_data=json.dumps({ # create json package {"message":"","username":"","room":""}
'message' : message,
'username' : username,
'room' : room,
}))
@sync_to_async
def save_message(self, username, room, message):
user = User.objects.get(username=username)
room = Room.objects.get(slug=room)
Message.objects.create(user=user, room=room, content=message)
ROOM.HTML
{{ room.slug|json_script:"json-roomname" }}
{{request.user.username|json_script:"json-username"}}
<script>
const roomName = JSON.parse(document.getElementById('json-roomname').textContent);
const userName = JSON.parse(document.getElementById('json-username').textContent);
const charSocket = new WebSocket(
(window.location.protocol === 'https:' ? 'wss' : 'ws') + '://'
+ window.location.host
+ '/ws/'
+ roomName
+ '/'
);