React родное соединение Websocket с каналами Django открыто, но сообщения не проходят

У меня есть собственное приложение (Android), которое взаимодействует с каналами Django. При подключении к моему серверу разработки через ws все работает нормально. Однако, когда я пытаюсь подключиться к своему удаленному серверу wss с тем же кодом, ничего не получается.

Соединение сокета отображается как OPEN. Я даже получаю это первое "connected" сообщение, отправленное с сервера моему приложению:

class RGConsumer(AsyncWebsocketConsumer):
    rooms = []

    async def connect(self):
        self.rooms = []
        await self.join_room('all')
        await self.accept()
        await self.send(text_data=json.dumps({'event': 'connected'}))

    async def join_room(self, room_name):
        if room_name not in self.rooms:
            self.rooms.append(room_name)
            await self.channel_layer.group_add(
                room_name,
                self.channel_name
            )

Проблема в том, что кроме этого первого сообщения больше ничего не проходит. Например, все, что я отправляю через эту функцию, никогда не будет получено приложением:

def send_to_all(event, data=None):
    message = {'type': 'channel_event', 'message': {'event': event, 'data': data}}
    channel_layer = get_channel_layer()
    async_to_sync(channel_layer.group_send)(
        'all',
        message
    )

Точно так же, когда я вызываю websocket.send в своем приложении, функция receive моего потребителя вообще не запускается.

Еще раз, это прекрасно работает на моем локальном сервере, поэтому я предполагаю, что код правильный. Только при подключении приложения к производственному серверу wss оно перестает работать (кроме первого хорошо принятого сообщения connected)

Кроме того, даже функция websocket.onclose не вызывается, если я решу перезапустить рабочий сервер.

Есть ли какие-либо дополнительные настройки, позволяющие правильно подключиться к серверу wss, которые я мог упустить?

Дайте мне знать, если нужен еще код. Я не уверен, что еще может быть необходимо.


person Ryan Pergent    schedule 31.05.2019    source источник
comment
У вас есть настройка ssl на вашем рабочем сервере? так как это wss, вам нужно настроить ssl. Также распечатайте каждое сообщение, которое сервер отправляет клиенту, и проверьте, каким было последнее сообщение и статус.   -  person Ken4scholars    schedule 03.06.2019
comment
Да, на prod-сервере настроен ssl. На самом деле у меня также есть веб-сайт (в дополнение к приложению), который без проблем подключается к WebSocket сервера через wss. Проблема с печатью каждого сообщения заключается в том, что у меня много активных пользователей и уже происходят десятки взаимодействий с веб-сокетами в секунду.   -  person Ryan Pergent    schedule 03.06.2019
comment
Вы добавили определенный обработчик async def channel_event(self, event) к своему потребителю?   -  person Mario Orlandi    schedule 03.06.2019
comment
@MarioOrlandi У меня есть обработчик async def channel_event(self, data). Я подозреваю, что код в порядке, потому что он работает без каких-либо проблем локально.   -  person Ryan Pergent    schedule 03.06.2019
comment
Вы проверили, что channel_event() регулярно вызывается один раз для любого сообщения * количество подключенных клиентов?   -  person Mario Orlandi    schedule 04.06.2019
comment
@MarioOrlandi находится в разработке. Это немного сложнее протестировать в производственной среде, но WS-связь между сервером и веб-сайтом (не приложением) работает отлично. Таким образом, я предполагаю, что он делает то, что должен. Однако проблема с приложением заключается в том, что ни сервер-приложение, ни связь приложение-сервер не работают.   -  person Ryan Pergent    schedule 04.06.2019
comment
Райан, возможно, ты прав, однако в таких ситуациях я бы ничего не предполагал и вместо этого все тестировал. Убедиться, что потребители регулярно вызываются как исключенные в производстве, было бы суперпользовательским; каким бы ни был ответ, позже вы можете сузить свое внимание либо до уровня канала, либо до стороны веб-сокетов, но не для обоих одновременно. И это также должно быть очень просто: просто создайте сообщение журнала, вызовите mail_admins(), включите флаг в Redis или что-то еще;)   -  person Mario Orlandi    schedule 04.06.2019
comment
@MarioOrlandi, чтобы попытаться сделать это, я создал отдельную конечную точку маршрута каналов, к которой буду подключаться только я, чтобы она отправляла мне электронное письмо при отправке сообщения. Оказывается, создание новой конечной точки фактически решило мою проблему (см. мой ответ)...   -  person Ryan Pergent    schedule 04.06.2019
comment
@ Райан, это звучит странно, не так ли? Тем не менее, я рад слышать, что у вас есть хотя бы рабочая конфигурация для работы в продакшене ;)   -  person Mario Orlandi    schedule 05.06.2019


Ответы (1)


Мне удалось решить эту проблему, создав другой маршрут каналов для мобильного соединения WebSocket.

(/ws/ для моего веб-сайта и /mobile-ws/ для приложения)

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

person Ryan Pergent    schedule 04.06.2019