Как добавить участников в одну и ту же комнату чата в Django Channels 2.1.1 на примере мультичата - PullRequest
0 голосов
/ 03 мая 2018

Используя Django Channels 2.1.1 и Django 2.0, я создаю сайт, на котором клиент нажимает кнопку и попадает в чат с одним сотрудником. Я начинаю с примера мультичата Эндрю Годвина.

Короче говоря: я не могу понять, как правильно добавлять сотрудников в группу, чтобы он мог получать и отправлять сообщения в чате.

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

Используя это понимание, лучшее, что я смог сделать, это добавить такую ​​функцию join_room(self, room_id), как это, что, вероятно, совершенно неправильно:

async def join_room_client(self, room_id):
    ...

    # Added to find all staff who are logged in
    authenticated_staff = get_all_logged_in_users()

    # Added to list staff who are in less than 3 chatrooms
    available_staff = []

    if len(authenticated_staff) > 0:

        for staff in authenticated_staff:
            if staff in users_and_rooms and len(users_and_rooms[staff]) in range(3):
                available_staff.append(staff)
                random_available_staff = random.choice(available_staff)

                # I thought receive_json() would look for "content", but I was wrong
                content = {
                    "command": "join",
                    "join": room_id,
                    "type": "chat.join",
                    "room_id": room_id,
                    "text": "Hello there!",
                    "username": random_available_staff,
                    "title": room.title,
                }

                # Helps to open room in conjunction with chat_join()?
                from channels.layers import get_channel_layer

                channel_layer = get_channel_layer()
                await channel_layer.send(users_and_channels[random_available_staff], content)

                # This allows staff to receive messages in the chatroom but not to reply.
                 await self.channel_layer.group_add(
                     room.group_name,
                     # The line below is staff's channel name, eg: specific.PhCvZeuI!aCOgcyvgDanT
                     # I got it by accessing self.channel_name in connect(self)
                     users_and_channels[random_available_staff],
                 )

            else:
                print("Staff are not yet ready.")

    else:
        print("There are no staff available.")

С этим кодом комната автоматически открывается в браузере персонала. Он может видеть сообщения клиента, но попытка ответить вызывает "ROOM_ACCESS_DENIED", что означает, что он не был добавлен в комнату. Но я думал, что сделал это с group.add(room.group_name, users_and_channels[random_available_staff]).

В любом случае, по-видимому, наиболее эффективным способом является отправка данных о комнате чата в экземпляр сотрудника receive_json(self, content), когда клиент нажимает кнопку, верно? Но функция получает данные из Javascript в шаблоне через это:

socket.send(JSON.stringify({
                        "command": "join",
                        "room": roomId
                    })

Если это возможно, как я могу отправить данные о чате клиента в receive_json() персонала, используя потребителей в самой consumer.py? Если нет, какие еще подходы я должен использовать?

1 Ответ

0 голосов
/ 04 мая 2018

Оригинал join_room(self, room_id) содержит следующие две важные строки:

# Store that we're in the room
self.rooms.add(room_id)

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

async def chat_join(self, event):
    ...
    # Right at the end
    self.rooms.add(event["room_id"])

Поскольку chat_join() вступает в игру после join_room(), это позволяет нам добавлять сотрудников по его собственному циклу, а не по клиенту.

Но если вы так добавляете пользователей в комнату, то для чего это нужно:

    await self.channel_layer.group_add(
        room.group_name,
        self.channel_name,
    )

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

...