Каналы Django между различными контейнерами докеров - PullRequest
0 голосов
/ 18 мая 2018

Я работаю с django channels, и у меня возникла проблема с отправкой сообщения с использованием channels

Context

У меня есть2 контейнера: celery-worker и api, я хочу отправлять данные через веб-сокеты из контейнера celery-worker в браузер через контейнер api, используя channels, вот изображение:

enter image description here

Вопрос

Знаете ли вы, как "инициализировать" каналы в api контейнере и использовать эти каналы внутри celery-worker контейнера?после celery-worker контейнер звонит только на Group('pablo').send(message) и автоматически отправляет в браузер.

Любой совет будет в порядке.

Примечание: Я пыталсяне почтовый код, потому что он очень обширный, и, возможно, это затруднит понимание вопроса, но если вы захотите, я могу опубликовать какой-то код, который вам нужен.

Ответы [ 2 ]

0 голосов
/ 25 октября 2018

Я создал пример (с простыми заданиями), который использует каналы Celery и Django 2 ( github ).Сельдерей отправляет сообщения на канал.Сообщения передаются клиентам, которые подключены к веб-сокету.

На стороне сервера у меня есть потребитель:

class TasksConsumer(AsyncWebsocketConsumer):

    async def connect(self):
        # One group name for all clients: 'tasks'
        self.group_name = 'tasks'
        await self.channel_layer.group_add(self.group_name, self.channel_name)
        await self.accept()

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

    async def receive(self, text_data):
        pass

    async def task_update_message(self, event):
        # Send message to channel
        await self.send(json.dumps(event))

Вы видите, что имя группы - «задачи».На стороне сельдерея рабочий звонит:

channel_layer = get_channel_layer()
async_to_sync(channel_layer.group_send)("tasks", msg)

Чтобы использовать каналы в рабочем коде, вам нужно установить настройки django:

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'server.settings')
import django
django.setup()

Надеюсь, это поможет!

0 голосов
/ 27 июня 2018

Вам нужно сообщить другим контейнерам, что вы зависите от них.Пример.Здесь вы видите, что PostgreSQL имеет зависимости от user_service и messages_service, вам нужно добавить это для каждого контейнера, который хочет использовать другие контейнеры, связанные или зависимые.Вот пример.

version: '3'
services:
db:
    image: postgres
    ports:
    - '5434:5434'
user_service:
    build: ""
    environment:
    - JWT_SECRET=mysecret_json_web_token_pass
    command: python user/app.py
    volumes:
    - .:/microservices
    ports:
    - "9001:9001"
    depends_on:
    - db
notification_service:
    build: ""
    environment:
    - JWT_SECRET=mysecret_json_web_token_pass
    command: python notification/app.py
    volumes:
    - .:/microservices
    ports:
    - "9002:9002"
    depends_on:
    - db

для вашего случая вы можете добавить зависящий_on: - сельдерей - redis

Вы также можете стабилизировать локальную сеть .. но вместо того, чтобы сделать это, я создалконтейнеры в одном и том же docker-составлении таким образом, что они знают друг друга.

Вот еще один пример

version: '2'  
services:  
nginx:
    image: nginx:latest
    container_name: nx01
    ports:
    - "8001:8001"
    volumes:
    - ../src:/src
    - ./static:/static
    - ./media:/media/
    - ./config/nginx:/etc/nginx/conf.d
    depends_on:
    - web
web:
    build: .
    container_name: dg01
    command: gunicorn mydjango.wsgi 0.0.0.0:8000

    depends_on:
    - db
    links:
    - redis
    volumes:
    - ../src:/src
    - ./static:/static
    - ./media:/media/
    expose:
    - "8001"
db:
    image: postgres:latest
    container_name: pq01
    ports:
    - "5432:5432"

redis:
    image: redis:latest
    container_name: rd01
    ports:
    - '6379:6379'

celery:
    build: .
    container_name: cl01
    command: celery worker --app=app.tasks
    volumes:
    - ..:/src
    links:
    - db
    - redis

для вызова его в вашем коде ... используйте его следующим образом.

CELERY_BROKER_URL = 'redis://redis:6379/0'
CELERY_RESULT_BACKEND = 'redis://redis:6379/0'
...