Подтвердить что ты не робот

Как определить статус сообщения (чтение/непрочитанное) в чате?

Как определить статус сообщения (чтение/непрочитанное). Чат реализуется с помощью протокола XMPP.

4b9b3361

Ответ 1

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

Ответ 3

Если вы хотите получить квитанции на чтение, вместо отправки автоматических квитанций о доставке сообщения отправьте их всякий раз, когда пользователь читает это сообщение. Каждое сообщение имеет соответствующее сообщение message_id. Используйте этот message_id для отправки квитанции о доставке для определенного прочитанного сообщения. Добавьте следующий код при подключении

//message delivery
    XMPPMessageDeliveryReceipts* xmppMessageDeliveryRecipts = [[XMPPMessageDeliveryReceipts alloc] initWithDispatchQueue:dispatch_get_main_queue()];
//don't write this line as it will send auto receipts whenever message will be delivered
    //xmppMessageDeliveryRecipts.autoSendMessageDeliveryReceipts = YES;
    xmppMessageDeliveryRecipts.autoSendMessageDeliveryRequests = YES;
    [xmppMessageDeliveryRecipts activate:self.xmppStream];

Я решил эту проблему, добавив атрибут chatStatus в свой объект сообщения. Для отправителя я сохранил значение chatStatus как отправленное, неотправленное или полученное (полученное другой стороной или нет). Для стороны получателя я сохранил значения как прочитанные или непрочитанные (прочитал ли я сообщение или нет, так что для непрочитанного сообщения я мог бы отправлять прочитанные квитанции).

Кнопка Click of send:

//Save to your Message Entity 

NSMutableDictionary *m = [[NSMutableDictionary alloc] init];
[m setObject: message_body forKey:@"message_body"];
[m setObject:messageID forKey:@"message_id"];
[m setObject:@"yes" forKey:@"isOutgoing"];
[m setObject:dateString forKey:@"date"];
[m setObject:timeString forKey:@"time"];
[m setObject:[NSDate date] forKey:@"timeStamp"];
[m setObject:yourId forKey:@"from"];
[m setObject:toId forKey:@"to"];

if (!Is_InternetAvailable]) {
 [m setObject:unsent forKey:@"chatStatus"];
}
else{
 [m setObject:sent forKey:@"chatStatus"];
}
[[CoreDataMethods sharedCoreDataMethods] saveUserMessage:m];
}

В cellForRowAtIndexPath:

if ([message isoutGoing]) {//If I have sent the message

        // Mine bubble
        if ([[messageDict valueForKey:@"chatStatus"] isEqualToString:unsent]) {
            //set unsent image
        }
        else if ([[messageDict valueForKey:@"chatStatus"] isEqualToString:sent]){
            //set sent image
        }
        else if ([[messageDict valueForKey:@"chatStatus"] isEqualToString:received]){
          //set Received Image
        }
    }
    else{
        // Other Bubble , Notify them that you have read the message if it is unread/new message

        if ([[messageDict valueForKey:@"chatStatus"] isEqualToString:unread]) {

            //send read receipt
                NSXMLElement *receivedelement = [NSXMLElement elementWithName:@"received" xmlns:@"urn:xmpp:receipts"];

                NSXMLElement *message = [NSXMLElement elementWithName:@"message" xmlns:@"jabber:client"];
                [message addAttributeWithName:@"to" stringValue:toId];
                [message addAttributeWithName:@"from" stringValue:fromID];
                [receivedelement addAttributeWithName:@"id" stringValue:[messageDict valueForKey:@"message_id"]];
                [message addChild:receivedelement];

                //XMPPMessage *generatedReceiptResponse = [[messageDict valueForKey:@"xmppMessage"] generateReceiptResponse];
                [[[kAppDelegate xmppHandler] xmppStream] sendElement:message];

                // update message entity
                [self updateChatStatus:read withMessageID:[messageDict valueForKey:@"message_id"]];
        }
    }

И, наконец, когда вы получите квитанцию ​​о доставке в didReceiveMessage, обновите chatStatus для получения

- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message{

if ([message hasReceiptResponse]) {//message read
//Update database message entity
 [self updateChatStatus:@"received" withMessageID:[message receiptResponseID]];
}
}

Вы можете установить значения chatStatus в соответствии с вашим требованием. Что касается неотправленных сообщений, я установил его как отправленный в делегат didSendMessage.

Примечание. В моем приложении мне нужно было просто показать статус чтения, отправки и отмены, а не статус доставки. Если вы также хотите показать статус доставки, то не комментируйте autoSendMessageDeliveryReceipts и всякий раз, когда сообщения читаются, отправьте строфу IQ отправителю вместо квитанции о доставке и соответствующим образом измените chatStatus.

Это просто основная идея, вы можете использовать ее в соответствии с вашими требованиями.

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

Ответ 4

Xmpp не имеет чтения/непрочитанной квитанции. Полученный результат - это то, что было реализовано в XEP-0184.