メッセージに問題 (遅延 + 重複) を引き起こす XMPP プッシュ通知。
XMPP + Ejabberd を使用したチャット アプリケーションの作成に成功しました。
プッシュ通知なし:
シングル チャット メッセージとグループ チャット メッセージの両方が完全に機能しています。
プッシュ通知の場合:
すべてが完全に機能する場合もあります。通知がトリガーされ、遅延や重複なしにメッセージが受信されます。
通知がトリガーされない場合がありますが (アプリがバックグラウンドにある場合)、メッセージは完全に受信されます。
通知がトリガーされることもありますが、メッセージは遅れて重複して受信されます。
サーバー側のすべてが正しく構成されています.彼らは、各セッションが1つの永続的なリソースに接続されていることを確認し、空白キープアライブを使用して接続を安定させ、接続が失われたときに同じリソースで再バインドするだけで問題を解決することをお勧めします.
ストリーム管理、xmppStream.enableBackgroundingOnSocket があり、アプリは Voice over IP サービスのバックグラウンド モードを有効にしています。
ユーザーがログアウトするか、アプリが終了すると、ストリームを破棄し、使用できないプレゼンスを送信します。
以下は、xmpp ストリーム プッシュ通知と接続/切断のコードです。
私はこれについて私の髪を引っ張っています. もしあなたが何か考えを持っているなら、私に知らせてください.
ありがとう。
#pragma mark - Connect/Disconnect
- (BOOL)connect {
if (!_xmppStream) {
NSLog(@"Setting up Stream");
[self setupStream];
}
if (![_xmppStream isDisconnected]) {
return YES;
}
NSString *jabberID = [[NSUserDefaults standardUserDefaults] stringForKey:@"userID"];
NSString *myPassword = [[NSUserDefaults standardUserDefaults] stringForKey:@"userPassword"];
if (jabberID == nil || myPassword == nil) {
return NO;
}
[_xmppStream setMyJID:[XMPPJID jidWithString:jabberID]];
_password = myPassword;
NSError *error = nil;
if (![_xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:&error]){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:[NSString stringWithFormat:@"Can't connect to server! %@", [error localizedDescription]] delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
[alert show];
return NO;
}
return YES;
}
- (void)disconnect {
[self goOffline];
[self teardownStream];
}
- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender {
[self goOnline];
//Stream Management
NSXMLElement *enable = [NSXMLElement elementWithName:@"enable" xmlns:@"urn:xmpp:sm:3"];
[enable addAttributeWithName:@"resume" stringValue:@"true"];
[_xsm.xmppStream sendElement:enable];
//Push
[self configurePushNotifications];
//
}
-(void)configurePushNotifications{
NSString *jabberID = [[NSUserDefaults standardUserDefaults] stringForKey:@"userID"];
NSXMLElement *iq = [NSXMLElement elementWithName:@"iq"];
[iq addAttributeWithName:@"type" stringValue:@"set"];
[iq addAttributeWithName:@"id" stringValue:idString];
NSXMLElement *push = [NSXMLElement elementWithName:@"push" xmlns:@"p1:push"];
NSXMLElement *keepalive = [NSXMLElement elementWithName:@"keepalive"];
[keepalive addAttributeWithName:@"max" integerValue:30];
NSXMLElement *session = [NSXMLElement elementWithName:@"session"];
[session addAttributeWithName:@"duration" integerValue:60];
NSXMLElement *body = [NSXMLElement elementWithName:@"body"];
[body addAttributeWithName:@"send" stringValue:@"all"];
[body addAttributeWithName:@"groupchat" stringValue:@"true"];
[body addAttributeWithName:@"from" stringValue:jabberID];
NSXMLElement *status = [NSXMLElement elementWithName:@"status"];
[status addAttributeWithName:@"type" stringValue:[NSString stringWithFormat:@"New message from %@",jabberID]];
NSXMLElement *offline = [NSXMLElement elementWithName:@"offline" stringValue:@"true"];
[push addChild:keepalive];
[push addChild:session];
[push addChild:body];
[push addChild:status];
[push addChild:offline];
NSXMLElement *notification = [NSXMLElement elementWithName:@"notification"];
[notification addChild:[NSXMLElement elementWithName:@"type" stringValue:@"applepush"]];
[notification addChild:[NSXMLElement elementWithName:@"id" stringValue:_userDeviceToken]];
[push addChild:notification];
NSXMLElement *appid = [NSXMLElement elementWithName:@"appid" stringValue:@"appid"];
[push addChild:appid];
[iq addChild:push];
[[self xmppStream] sendElement:iq];
}
- (void)setupStream {
_xmppStream = [[XMPPStream alloc] init];
_xmppStream.hostName = kHostName;
_xmppStream.hostPort = kHostPort;
_xmppStream.enableBackgroundingOnSocket = YES;
[_xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
//XMPPReconnect
_xmppReconnect = [[XMPPReconnect alloc] init];
[_xmppReconnect activate:_xmppStream];
//Stream Management
_xsm = [[XMPPStreamManagement alloc] init];
[_xsm enableStreamManagementWithResumption:YES maxTimeout:0];
[_xsm activate:_xmppStream];
//Last Activity
_xmppLastActivity = [[XMPPLastActivity alloc] initWithDispatchQueue:dispatch_get_main_queue()];
[_xmppLastActivity addDelegate:self delegateQueue:dispatch_get_main_queue()];
[_xmppLastActivity activate:_xmppStream];
}
- (void)goOnline {
XMPPPresence *presence = [XMPPPresence presence];
[[self xmppStream] sendElement:presence];
}
- (void)goOffline {
XMPPPresence *presence = [XMPPPresence presenceWithType:@"unavailable"];
[[self xmppStream] sendElement:presence];
}
- (void)teardownStream {
[_xmppStream disconnect];
[_xmppStream removeDelegate:self];
[_xmppReconnect removeDelegate:self];
[_xmppLastActivity removeDelegate:self];
[_xmppReconnect deactivate];
_xmppStream = nil;
_xmppReconnect = nil;
_xmppLastActivity = nil;
}