Как обрабатывать сообщения чата MUC - дублирование сообщений

Я реализовал чат один на один, используя структуру XMPP. Он имеет обширную поддержку в чате один на один. Архивация и извлечение сообщений очень просты. Но я вижу, очень сложно обрабатывать сохранение и отображение сообщений группового чата. Сортировка и предикаты не работают. отображаются повторяющиеся сообщения.

Вот как я присоединяюсь к комнате, прежде чем получить свое уже сохраненное сообщение)

XMPPRoomCoreDataStorage *coreDataRoomStorage=[self appDelegate].xmppRoomCoreDataStorage;
XMPPRoom *room=[[XMPPRoom alloc]initWithRoomStorage:coreDataRoomStorage jid:user.bareJid];
    [room activate:[self appDelegate].xmppStream];
    [room addDelegate:[self appDelegate] delegateQueue:dispatch_get_main_queue()];
    [room joinRoomUsingNickname:user.user_name history:nil];

Вижу, есть несколько избыточных сохранений сообщений. Одно сообщение сохраняется 3-4 раза. Что я могу делать неправильно. Некоторое тело, пожалуйста, помогите! Это код, который я делаю для обработки сообщений в комнате.

- (NSFetchedResultsController *)fetchedResultsController{
if (fetchedResultsController == nil)
{
    NSManagedObjectContext *moc = [[self appDelegate] managedObjectContext_message];

    NSEntityDescription *entity = [NSEntityDescription entityForName:@"XMPPMessageArchiving_Message_CoreDataObject"
                                              inManagedObjectContext:moc];
    NSPredicate *predicate=[NSPredicate predicateWithFormat:@"bareJidStr=%@",_thisRoom.roomJID.bare];
    NSSortDescriptor *sd1 = [[NSSortDescriptor alloc] initWithKey:@"timestamp" ascending:YES];
    NSArray *sortDescriptors = [NSArray arrayWithObjects:sd1, nil];
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    [fetchRequest setEntity:entity];
    [fetchRequest setSortDescriptors:sortDescriptors];
    [fetchRequest setPredicate:predicate];
    [fetchRequest setFetchBatchSize:20];
    fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
                                                                   managedObjectContext:moc
                                                                     sectionNameKeyPath:nil
                                                                              cacheName:nil];
    [fetchedResultsController setDelegate:self];

    NSError *error = nil;
    if (![fetchedResultsController performFetch:&error])
    {
        DDLogError(@"Error performing fetch: %@", error);
    }   
}
return fetchedResultsController;}

person alin andrews    schedule 31.10.2014    source источник
comment
почему минусовали? Вопрос подлинный, и ответ на этот вопрос поможет любому, кто использует групповой чат с использованием фреймворка robbie hanson xmpp. Существует проблема повторения одних и тех же сообщений по 3-4 раза в этом фреймворке. если кто-то нашел обходной путь, это спасет   -  person alin andrews    schedule 01.11.2014
comment
Не волнуйтесь, приятель. Будьте счастливы. Теперь вы можете видеть свой вопрос без проголосовавших против. Я проголосовал за ваш вопрос. Просто потому, что я полностью согласен с вашим вопросом. Это настоящий вопрос.   -  person Arpan Dixit    schedule 06.11.2014


Ответы (3)


Я думаю, что нашел ответ на проблему дублирования сообщений. Основная проблема заключалась в том, что сообщение, которое я отправляю в комнату, повторялось при каждом присоединении к комнате. Что я делал, так это то, что всякий раз, когда я отправлял сообщение, я сохранял идентификатор устройства в качестве дочернего элемента для xmpppmessage. При получении сообщения я проверяю дочерний элемент. Если идентификатор устройства совпадает, это то же самое сообщение, которое я отправлял ранее, и оно уже находится в основных данных, поэтому отмените сообщение.

- (void)sendMessageWithBody:(NSString *)messageBody
{
if ([messageBody length] == 0) return;

NSXMLElement *body = [NSXMLElement elementWithName:@"body" stringValue:messageBody];
XMPPMessage *message = [XMPPMessage message];
[message addChild:body];


//device id is used, so that the my message element will be unique 
NSString *uuidString=[UIDevice currentDevice].identifierForVendor.UUIDString;
NSXMLElement *myMsgLogic=[NSXMLElement elementWithName:@"myMsgLogic" stringValue:uuidString];
[message addChild:myMsgLogic];

[self sendMessage:message];
}

Затем при получении сообщения в xmppstream. справиться с этим В XMPPRoomCoreDataStorage есть метод, называемый

 - (void)handleIncomingMessage:(XMPPMessage *)message room:(XMPPRoom *)room

на этом сделать логику сортировки сообщений. Не вставляя весь код:

- (void)handleIncomingMessage:(XMPPMessage *)message room:(XMPPRoom *)room
{
  XMPPLogTrace();

XMPPJID *myRoomJID = room.myRoomJID;
XMPPJID *messageJID = [message from];


NSString *uuidString=[UIDevice currentDevice].identifierForVendor.UUIDString;

NSString *messageLogic= [[message elementsForName:@"myMsgLogic"].firstObject stringValue];

if ([uuidString isEqualToString:messageLogic]) {
    return;
}

 //rest code is already there in the method
 }
person alin andrews    schedule 05.11.2014
comment
Привет @alin, я хочу спросить одну вещь, как мы можем сохранить групповой чат в основных данных? Я не могу получить данные из основных данных, как мы можем получить для однорангового чата. - person Sushil Sharma; 20.04.2015
comment
Сушил. Объект XMPProomMessageCoreDataStorageObject. Это объект для сообщений комнаты. Укажите правильные параметры для получения основных данных (например, jids комнаты, поток и т. д.). Затем вы получите сохраненные сообщения комнаты. - person alin andrews; 24.04.2015
comment
Спасибо за ответ @Alin, но для получения нам нужно активировать coreDataStorage в appDelegate. Как мы это делаем? Как активировать coreDataStorage? - person Sushil Sharma; 24.04.2015
comment
@alinandrews Я попробовал ваше решение, но все еще получаю повторяющиеся сообщения, не могли бы вы рассказать мне, как это исправить. Я уже задаю вопрос stackoverflow.com/questions/29538479/ - person alok srivastava; 03.05.2015
comment
@alinandrews Выполнение Xmpp быстрее, чем обычное выполнение iOS. Можно сказать, что это патч, но проблема была в активном потоке. Но Эй, хорошая логика. - person Siten; 03.12.2015

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

[room activate:[self appDelegate].xmppStream];

Когда мы когда-либо активируем эту комнату, она фактически добавляет слушателя. Поэтому активен только один раз.

person Siten    schedule 03.12.2015

Другой способ сделать это — создать NSPredicate:

Получите ваши эхо-сообщения (это означает, что вы отправили сообщение в комнате, и сервер XMPP получил это сообщение и повторно отправил всем (широковещательным) обитателям комнаты с голым видом [email protected] .com)

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT (messageStr CONTAINS[cd] %@)", [NSString stringWithFormat:@"from=\"%@\"",[xmpp sharedInstance].xmppStream.myJID.bare]];

Если вы хотите показать отправленные вами сообщения ( [email protected]), измените строку from на to

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT (messageStr CONTAINS[cd] %@)", [NSString stringWithFormat:@"to=\"%@\"",[xmpp sharedInstance].xmppStream.myJID.bare]];

Таким образом, нет необходимости изменять структуру.

person Moral    schedule 19.01.2015
comment
Хорошая Мораль. Я пробовал это. Но при очень быстрой доставке сообщений сообщения повторялись. А также метод msgLogic может выполняться без каких-либо операций с базой данных. Итак, я остановил свой выбор на этом методе. - person alin andrews; 20.01.2015
comment
@alinandrews ты нашел решение? у меня такой же вопрос - person Siten; 26.11.2015