2014-10-31 133 views
1

我已经使用XMPP框架实现了一对一聊天它在一对一聊天中提供了广泛的支持。消息归档和提取非常简单。但是我看到,在处理群聊信息保存和显示方面非常困难。排序和谓词失败。显示重复的消息。如何处理MUC聊天消息 - 复制消息

这是我如何加入一个房间之前,我去找我已保存的消息)

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;} 
+0

为什么downvoted?问题是真的,这个问题的答案将有助于任何人使用robbie hanson xmpp框架进行群聊。在这个框架中有相同的信息被重复使用3-4次。如果有人发现任何工作,这将节省 – 2014-11-01 10:04:13

+0

不要担心哥们。很高兴。现在你可以看到你的问题没有投票。我已经投了你的问题。仅仅因为我完全同意你质疑它的真正问题。 – 2014-11-06 12:50:58

回答

1

我想我找到了一个消息重复问题的答案。 主要问题是我在房间里发送的消息在每个房间加入时都会重复。 我所做的是当我发送一条消息时,我保留了一个deviceID作为xmppmessage的子元素。在接收消息时,我检查了子元素。如果devce id匹配,它与我先前发送的消息相同,并且它已经存在于核心数据中,那么丢弃该消息。

- (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 
} 
+0

您好@alin,我想问一个问题,我们如何在核心数据中保存群聊?我无法从核心数据中检索数据,就像我们可以检索对等对话一样。 – 2015-04-20 09:48:45

+0

Sushil。 XMPPRoomMessageCoreDataStorageObject。这是房间信息的对象。为核心数据提取提供正确的参数(如房间jids,流等)然后,您将获得保存的房间消息。 – 2015-04-24 06:56:34

+0

感谢您的回复@ Alin,但对于检索,我们需要在appDelegate中激活coreDataStorage。我们如何做到这一点?如何激活coreDataStorage? – 2015-04-24 07:39:14

0

另一种方法是创建一个NSPredicate

找回您的回应信息(这意味着你已经发送了房间内的消息,XMPP服务器已收到房间的该消息并重新发送给所有(广播)乘员裸像[email protected]

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

如果你想显示已由您发送的消息( [email protected]),那么串通过更改为

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

所以,没有必要修改的框架。

+0

好道德。我曾试过这个。但是在非常快速的消息传递中,消息是重复的。而且msgLogic方法也可以在没有任何数据库操作的情况下完成。所以,我选择了这种方法。 – 2015-01-20 09:12:42

+0

@alinandrews您是否得到了解决方案?我有同样的问题 – Siten 2015-11-26 11:36:47

1

经过搜索和尝试了很多,我有一个结论,收到组重复消息。 XMPP工作最好的,但实际的问题是:

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

当过我们活动的那个房间,它实际上增加了一个监听器。所以只能激活一次