XMPP push notifications causing problems (delay + duplications) in messages -
xmpp push notifications causing problems (delay + duplications) in messages.
i have created chat application using xmpp + ejabberd.
without push notifications:
both single , group chat messages working perfectly.
with push notifications:
sometimes works perfectly.notifications triggered , messages received out delay or duplications.
sometimes no notifications triggered (while app in background) messages received perfectly.
sometimes notifications triggered messages received delay , duplications.
everything on sever side configured correctly.they advised fix issues making sure each session connects 1 persistent resource, making connection stable using whitespace keep alive , when connection lost rebinding same resource.
i have stream management,xmppstream.enablebackgroundingonsocket , app provides voice on ip services background mode enabled.
when user logs out or app terminated teardown stream , send unavailable presence.
below code xmpp stream push notifications , connect/disconnect.
i pulling out hair on this.if guys have idea please let me know.
thanks.
#pragma mark - connect/disconnect - (bool)connect { if (!_xmppstream) { nslog(@"setting 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 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 %@",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; }
you need make sure passing resource when connect ejabberd. resource should randomly generated on first app install , on subsequent login, should use same resource. otherwise created new long running detached session on each new login on server , causing messages routed pending sessions. when expires routed again etc.
in xmpp, resource identifier of device basically. need generate jid login string of form "user@domain/resource"
Comments
Post a Comment