This commit is contained in:
2025-10-07 17:03:14 +08:00
parent 8a4fec28cf
commit 22d4a9057b
13 changed files with 873 additions and 1 deletions

35
oj/asgi.py Normal file
View File

@@ -0,0 +1,35 @@
"""
ASGI config for oj project.
It exposes the ASGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/5.2/howto/deployment/asgi/
"""
import os
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
from utils.shortcuts import get_env
production_env = get_env("OJ_ENV", "dev") == "production"
if production_env:
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "oj.production_settings")
else:
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "oj.dev_settings")
# Initialize Django ASGI application early to ensure the AppRegistry
# is populated before importing code that may import ORM models.
django_asgi_app = get_asgi_application()
# Import routing after Django setup
from oj.routing import websocket_urlpatterns
application = ProtocolTypeRouter(
{
"http": django_asgi_app,
"websocket": AuthMiddlewareStack(URLRouter(websocket_urlpatterns)),
}
)

11
oj/routing.py Normal file
View File

@@ -0,0 +1,11 @@
"""
WebSocket URL Configuration for oj project.
"""
from django.urls import path
from submission.consumers import SubmissionConsumer
websocket_urlpatterns = [
path("ws/submission/", SubmissionConsumer.as_asgi()),
]

View File

@@ -28,12 +28,14 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Applications
VENDOR_APPS = [
"daphne", # Channels ASGI server - must be first
"django.contrib.auth",
"django.contrib.sessions",
"django.contrib.contenttypes",
"django.contrib.messages",
"django.contrib.staticfiles",
"rest_framework",
"channels",
"django_dramatiq",
"django_dbconn_retry",
]
@@ -92,6 +94,9 @@ TEMPLATES = [
]
WSGI_APPLICATION = "oj.wsgi.application"
# ASGI Application for WebSocket support
ASGI_APPLICATION = "oj.asgi.application"
# Password validation
# https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators
@@ -212,6 +217,18 @@ CACHES = {"default": redis_config(db=1)}
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"
# Channels Configuration
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {
"hosts": [(REDIS_CONF["host"], REDIS_CONF["port"])],
"capacity": 1500, # 每个频道的最大消息数
"expiry": 10, # 消息过期时间(秒)
},
},
}
DRAMATIQ_BROKER = {
"BROKER": "dramatiq.brokers.redis.RedisBroker",
"OPTIONS": {