XMPP 推送通知导致消息出现问题(延迟 + 重复) [英] XMPP push notifications causing problems (delay + duplications) in messages

查看:29
本文介绍了XMPP 推送通知导致消息出现问题(延迟 + 重复)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

XMPP 推送通知导致消息出现问题(延迟 + 重复).

XMPP push notifications causing problems (delay + duplications) in messages.

我已经使用 XMPP + Ejabberd 成功创建了一个聊天应用程序.

I have successfully created a chat application using XMPP + Ejabberd.

没有推送通知:

单人和群聊消息都运行良好.

Both single and group chat messages are working perfectly.

使用推送通知:

有时一切正常.触发通知并接收消息,没有任何延迟或重复.

Sometimes everything works perfectly.Notifications are triggered and messages are received with out any delay or duplications.

有时不会触发通知(当应用程序在后台时)但可以完美接收消息.

Sometimes no notifications are triggered (while app in background) but messages are received perfectly.

有时会触发通知,但会延迟和重复接收消息.

Sometimes notifications are triggered but messages are received with delay and duplications.

服务器端的所有内容都配置正确.他们建议通过确保每个会话连接到一个持久资源来解决您的问题,使用空格保持连接使连接稳定,并且在连接丢失时只需重新绑定相同的资源即可.

Everything on the sever side is configured correctly.They advised to fix your issues by making sure each session connects with one persistent resource, making connection stable using whitespace keep alive and when connection is lost just rebinding with same resource.

我有流管理,xmppStream.enableBackgroundingOnSocket 和应用程序提供 IP 语音服务后台模式启用.

I have stream management,xmppStream.enableBackgroundingOnSocket and App provides Voice over IP services background mode enabled.

当用户注销或应用程序终止时,我会拆除流并发送一个不可用的状态.

When user logs out or app is terminated i teardown the stream and send an unavailable presence.

下面是我的 xmpp 流推送通知和连接/断开连接的代码.

Below is my code for xmpp stream push notifications and connect/disconnect.

我正在为此拔头发.如果你们有任何想法,请告诉我.

I am pulling out my hair over this.if you guys have any idea please let me know.

谢谢.

#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;

  }

推荐答案

您需要确保在连接到 ejabberd 时正在传递资源.该资源应该在第一次安装应用程序和随后登录时随机生成,您应该始终使用相同的资源.否则,您将在服务器上的每次新登录时创建一个新的长时间运行的分离会话,并导致消息被路由到所有挂起的会话.当这些过期时,它们会再次路由等.

You need to make sure that you are passing the resource when you connect to ejabberd. The resource should be randomly generated on first app install and on subsequent login, you should always use the same resource. Otherwise you are created a new long running detached session on each new login on the server and causing messages to be routed to all pending sessions. When those expires they are routed again etc.

在 XMPP 中,资源基本上是设备的标识符.您需要使用user@domain/resource"形式的字符串生成用于登录的JID

In XMPP, the resource is the identifier of the device basically. You need to generate the JID for login with a string of form "user@domain/resource"

这篇关于XMPP 推送通知导致消息出现问题(延迟 + 重复)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆