У меня есть собственное приложение (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, которые я мог упустить?
Дайте мне знать, если нужен еще код. Я не уверен, что еще может быть необходимо.
Да, на prod-сервере настроен ssl. На самом деле у меня также есть веб-сайт (в дополнение к приложению), который без проблем подключается к WebSocket сервера через wss. Проблема с печатью каждого сообщения заключается в том, что у меня много активных пользователей и уже происходят десятки взаимодействий с веб-сокетами в секунду.
Добавили ли вы специальный обработчик «async def channel_event (self, event)» к своему потребителю?
@MarioOrlandi У меня есть обработчик async def channel_event(self, data). Я подозреваю, что код в порядке, потому что он работает без каких-либо проблем локально.
Вы проверили, что channel_event() регулярно вызывается один раз для любого сообщения * количество подключенных клиентов?
@MarioOrlandi находится в разработке. Это немного сложнее протестировать в производстве, но связь WS сервер-> веб-сайт (не приложение) работает отлично. Таким образом, я предполагаю, что он делает то, что должен. Однако проблема с приложением заключается в том, что ни сервер-> приложение, ни приложение-> сервер не работают.
Райан, возможно, ты прав, однако в таких ситуациях я бы ничего не предполагал и вместо этого все тестировал. Убедиться, что потребители регулярно вызываются как исключенные в производстве, было бы суперпользовательским; каким бы ни был ответ, позже вы можете сузить свое внимание либо до уровня канала, либо до стороны веб-сокетов, но не для обоих одновременно. И это также должно быть очень просто: просто создайте сообщение журнала, вызовите mail_admins(), включите флаг в Redis или что-то еще;)
@MarioOrlandi, чтобы попытаться сделать это, я создал отдельную конечную точку маршрута каналов, к которой буду подключаться только я, чтобы она отправляла мне электронное письмо при отправке сообщения. Оказывается, создание новой конечной точки фактически решило мою проблему (см. мой ответ)...
@ Райан, это звучит странно, не так ли? Тем не менее, я рад слышать, что у вас есть хотя бы рабочая конфигурация для работы в продакшене ;)





Мне удалось решить эту проблему, создав другой маршрут каналов для мобильного соединения WebSocket.
(/ws/ для моего сайта и /mobile-ws/ для приложения)
Я до сих пор не понимаю, почему использование той же конечной точки, что и мой веб-сайт, было проблемой, или почему это работало в разработке, но не в производстве. Я бы с радостью принял лучший ответ, чем этот.
У вас есть настройка ssl на вашем рабочем сервере? так как это wss, вам нужно настроить ssl. Также распечатайте каждое сообщение, которое сервер отправляет клиенту, и проверьте, каким было последнее сообщение и статус.