我使用Django channels rest framework创建了一个带有两个websockets连接的应用程序。在本地,一切正常。我有这样的设置:
#routing.py
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
from django.urls import re_path
from gnss.consumers import CoordinateConsumer # noqa
from operations.consumers import OperationConsumer # noqa
websocket_urlpatterns = [
re_path(r'ws/coordinates/', CoordinateConsumer.as_asgi()),
re_path(r'ws/operations/', OperationConsumer.as_asgi()),
]
application = ProtocolTypeRouter({
'http': get_asgi_application(),
'websocket': AuthMiddlewareStack(
URLRouter(websocket_urlpatterns)
),
})
# consumers.py
from djangochannelsrestframework.decorators import action # noqa
from djangochannelsrestframework.generics import GenericAsyncAPIConsumer # noqa
from djangochannelsrestframework.observer import model_observer # noqa
from djangochannelsrestframework.observer.generics import action # noqa
from djangochannelsrestframework.permissions import AllowAny # noqa
from .models import Coordinate
from .serializers import CoordinateSerializer
class CoordinateConsumer(GenericAsyncAPIConsumer):
queryset = Coordinate.objects.all()
serializer_class = CoordinateSerializer
permission_classes = (AllowAny,)
@model_observer(Coordinate)
async def coordinates_activity(self, message, action=None, **kwargs):
await self.send_json(message)
@coordinates_activity.serializer
def coordinates_activity(self, instance: Coordinate, action, **kwargs):
return dict(CoordinateSerializer(instance).data,
action=action.value, pk=instance.pk)
@action()
async def subscribe_to_coordinates_activity(self, request_id, **kwargs):
await self.coordinates_activity.subscribe(request_id=request_id)
至于consumers.py的**ws/operations/**也是一样的。当我在开发服务器(python www.example.com runserver)的本地机器上运行我的Django应用程序时manage.py,一切都很好。但是由于某种原因,当我在docker-compose中运行我的应用程序时,ws/operations/工作,但ws/coordinates不工作。由于某种原因,我没有收到来自Django的消息。
我的 composer
version: "3.7"
x-api-common: &api
build: ./backend
restart: always
env_file: ./config/api/.env
volumes:
- ./backend/api:/opt/code
- static_volume:/home/app/web/staticfiles
- media_volume:/home/app/web/media
networks:
- nginx_network
- postgres_network
depends_on:
- redis
- postgres
services:
wsgi:
<<: *api
command: "bash /opt/code/docker-wsgi-entrypoint.sh"
container_name: operations_wsgi
environment:
is_wsgi: 'true'
ports:
- 8000:8000
asgi:
<<: *api
command: "bash /opt/code/docker-asgi-entrypoint.sh"
container_name: operations_asgi
ports:
- 8001:8001
depends_on:
- wsgi
admin:
<<: *api
container_name: operations_admin
ports:
- 8002:8002
depends_on:
- wsgi
command: gunicorn api.wsgi:application --bind 0.0.0.0:8002 --workers 2 --timeout 600
web:
build:
context: ./frontend
dockerfile: Dockerfile
restart: "on-failure"
ports:
- 80:80
volumes:
- ./frontend:/app
- '/app/node_modules'
- static_volume:/home/app/web/staticfiles
- media_volume:/home/app/web/media
depends_on:
- wsgi
- asgi
- admin
networks:
- nginx_network
redis:
image: "redis:6.2.7-alpine"
restart: always
command:
- /bin/sh
- -c
- redis-server --requirepass "$${REDIS_PASSWORD:?REDIS_PASSWORD variable is not set}"
ports:
- "6379:6379"
env_file:
- ./config/redis/.env
networks:
- nginx_network
postgres:
image: postgres:13.0
restart: always
ports:
- 5432:5432
env_file: config/postgres/.env
networks:
- postgres_network
volumes:
- ./data/postgres-data:/var/lib/postgresql/data
rabbitmq:
image: 'rabbitmq:3.6-management-alpine'
restart: always
ports:
- '5672:5672'
- '15672:15672'
env_file: config/rabbitmq/.env
networks:
nginx_network:
driver: bridge
postgres_network:
driver: bridge
volumes:
static_volume:
media_volume:
我的nginx配置
upstream wsgi_server {
server wsgi:8000;
}
upstream asgi_server {
server asgi:8001;
}
upstream admin_server {
server admin:8002;
}
server {
listen 80;
server_name localhost;
charset utf-8;
server_tokens off;
client_max_body_size 20M;
resolver 10.0.0.2 valid=300s;
resolver_timeout 10s;
location ~* ^/ws/ {
proxy_pass http://asgi_server;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_set_header REMOTE_ADDR $remote_addr;
}
location ~ ^/static/(?<base_path>rest_framework|admin|drf-yasg)/(?<tail>.*)$ {
autoindex on;
alias /home/app/web/staticfiles/$base_path/$tail;
}
location ~ ^/media/(?<base_path>images)/(?<tail>.*)$ {
autoindex on;
alias /home/app/web/media/$base_path/$tail;
add_header Content-disposition "attachment";
}
location ~ ^/api|swagger|redoc/ {
proxy_pass http://wsgi_server;
proxy_pass_request_headers on;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
}
location ~ ^/admin/ {
proxy_pass http://admin_server;
proxy_pass_request_headers on;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
}
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
我不知道这是怎么了
1条答案
按热度按时间dgtucam11#
要解决此问题,请执行以下操作:
1.将def ready()函数添加到apps.py,如下所示:
1.这样配置nginx:
这是两个endpoints ws/operations和ws/coordinates的示例