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

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

Ответы [ 4 ]

6 голосов
/ 14 сентября 2011

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

2 голосов
/ 17 февраля 2016

Если вы хотите получить прочитанные квитанции, то вместо отправки квитанций автоматической доставки сообщений отправляйте их всякий раз, когда пользователь читает это сообщение. Каждое сообщение имеет соответствующий 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 как отправленное, неотправленное или полученное (полученное другой стороной или нет). Для стороны получателя я сохранил значения как прочитанные или непрочитанные (прочитал ли я сообщение или нет, чтобы в случае непрочитанного сообщения я мог отправить прочитанные квитанции).

При нажатии кнопки отправки:

//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 раздел IQ вместо квитанции о доставке и изменяйте chatStatus соответствующим образом.

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

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

2 голосов
/ 18 февраля 2015

Я думаю, вам нужно использовать отображаемый маркер чата, за http://xmpp.org/extensions/xep-0333.html

0 голосов
/ 09 декабря 2015

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

...