Как определить, чтобы сообщение для определенного набора слушателей? - PullRequest
0 голосов
/ 15 апреля 2019

Как определить сообщение для определенного набора слушателей?

Например, у меня есть Люк, Джейсон и Брюс в ChatRoom A. Лиза в Chatroom B. И у каждого участника есть экран списка сообщений, который отображает толькопоследнее сообщение группового чата.

У меня есть сокет-соединение, установленное в каждом чате для прослушивания входящих сообщений.Групповые сообщения из определенного чата будут иметь идентификатор комнаты вместе с сообщением.Вопрос в том, как определить websocket для отправки сообщений только тем людям, которые подписались на этот чат?

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

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

Вот моя функция соединения:

class GroupMessageListConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        self.userId = str(self.scope['query_string'])[2:-1].split("=")[1]

        # self.eventId = self.scope['url_route']['kwargs']['eventId']

        print('GroupMessageListConsumer connected self.userId:{}'.format(self.userId))

        # print('GroupMessageListConsumer connected self.userId:{}'.format(self.userId))
        # print('GroupMessageListConsumer connected self.eventId:{}'.format(self.eventId))

        # Join room group
        await self.channel_layer.group_add(
            self.userId,
            self.channel_name
        )

        await self.accept()


    async def disconnect(self, close_code):
        # Leave room group
        await self.channel_layer.group_discard(
            self.userId,
            self.channel_name
        )

1 Ответ

0 голосов
/ 17 апреля 2019

Создайте отдельную модель Room

class Room(models.model):
    users = models.ManyToManyField(
        "User",
        related_name='rooms',
        blank=True,
        symmetrical=False)

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

event_type: Что вызвало это событие?пользователь отправляет сообщение?вы отправляете уведомление пользователю?Это предупреждение?

data: Какие данные отправляются вместе?

errors: есть ли ошибки?

Пример полезной нагрузки:

{ "event_type": "send_message", "data": { "message": "Hi", "room": 143, }, "errors": None }

{ "event_type": "send_notif", "data": { "message": "You received a friend request from xxx", "type": "friend_request", }, "errors": None }

Потребитель.py

class GroupMessageListConsumer(AsyncWebsocketConsumer):
    user = None
    async def connect(self):
        self.user = self.scope["user"] #authenticated user either passed in through session or by token authentication

        print("connection request received.")

        await self.accept()
        print("connection accepted")

        #channel/channel_name is the current open socket connection between your browser and the server

        # Join channel or user to his rooms
        for room in self.user.rooms:
            await self.channel_layer.group_add(
                room.id,
                self.channel_name
            )

    async def disconnect(self, close_code):
        #remove current channel from listening to messages as it is closed or disconnected
        # Leave channel from all rooms
        for room in self.user.rooms:
            await self.channel_layer.group_discard(
                room.id,
                self.channel_name
            )
        print("channel disconnected.")
        raise StopConsumer()


    async def receive(self,text_data):
        print("message received.")
        text_data_json = json.loads(text_data)
        #always maintain payload with three main fields: "event_type", "data", "errors"
        event_type = text_data_json['event_type']
        data = text_data_json['data']
        if event_type=="send_message":
            #check whether user is allowed to send messages to room 143

            #Then send the message to that room.
            await self.channel_layer.group_send(
                data["room"],
                {
                    'type': "send_message", #call the respective event "async def send_message(self, event)" see below
                    'message': {
                        'event_type': event_type,
                        'data': {"message": data["message"], "user": self.user.id},
                        'errors': None
                    }
                }
            )
        else:
            print("event_type unknown")

    async def send_message(self, event):
        message =  event['message']
        # Send message to WebSocket
        await self.send(text_data=json.dumps({
            'message': message
        }))
...