I am getting 404 error while adding user to contact using roster
Here is my code
NSString * buddyNameJID = #"vinod#192.168.1.45";
XMPPJID *jid = [XMPPJID jidWithString:buddyNameJID];
[[appDelegate xmppRoster] addUser:jid withNickname:#"vinod"];
[[appDelegate xmppRoster]subscribePresenceToUser:jid];
after this getting error
<presence xmlns="jabber:client" to="kishore#eswks45/5r493h8jj8" from="vinod#192.168.1.45" type="error"><error code="404" type="cancel"><remote-server-not-found xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/></error></presence>
I have checked so many sites so many question but didn't get any solution
Related
I am working on a chat application where I set my xmppHostName- 'myserver' and server port -5222. First I created a user on xmpp through my application and it got registered on xmpp but there was an authentication error (although my user id and password were both same). Then I solved this authentication issue by using following method-
NSError *authenticateError = nil;
XMPPPlainAuthentication *plainAuth = [[XMPPPlainAuthentication alloc] initWithStream:self.xmppStream password:password];
if (![_xmppStream authenticate:plainAuth error:&authenticateError]) {
NSLog(#"Authentication errorrrr: %#", authenticateError.localizedDescription);
}
and the authentication error is gone, and my user is online but when I try to send any messages, the server replies with an error through otherserver:
<message xmlns="jabber:client" id="ACC2AAA6-42CE-4590-95A0-C4B28BE9BF04" to="97#otherserver/4ywme5xjh0" from="62#myserver" type="error"><error code="404" type="cancel"><remote-server-not-found xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/></error></message>
where, 97 is my user id and 62 is front users id. Below is my code for sending xmpp message:
NSXMLElement *body = [NSXMLElement elementWithName:#"body"];
[body setStringValue:messageBody];
NSXMLElement *subject = [NSXMLElement elementWithName:#"subject"];
[subject setStringValue:subjectName];
[message addAttributeWithName:#"to" stringValue:[user stringByAppendingString:myserver]];
[message addChild:body];
[message addChild:subject];
[self.xmppStream sendElement:message];
Here, 'myserver' is my server's hostname and the server replies from another server 'otherserver'. I am sure that I am not setting this 'otherserver' anywhere in my application, then how is this possible that it replies through it?
Trying to create a very simple proof of concept iOS xmpp app with the robbiehanson xmpp frame work, just need to be able to send and receive messages and roster data. I can authenticate and send messages successfully, but when users attempt to respond to my messages I do not receive them. I have implemented the didReceiveMessage delegate method as follows:
-(void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message {
NSLog(#"incoming message: %#", message);
}
but I never receive this log. If I log in with the existing web app or android app that communicates with this xmpp server I receive these messages, so I'm inclined to believe they are formatted properly. Is there a module I need to add to the XMPPStream for receiving messages? I'm setting up the stream like this (some of the string values have been changed for security and what not):
stream = [[XMPPStream alloc] init];
stream.enableBackgroundingOnSocket = YES;
stream.hostName = #"hostname.com";
stream.hostPort = 5222;
XMPPRosterCoreDataStorage* xmppRosterStorage = [[XMPPRosterCoreDataStorage alloc] initWithInMemoryStore];
XMPPRoster* xmppRoster = [[XMPPRoster alloc] initWithRosterStorage:xmppRosterStorage];
xmppRoster.autoFetchRoster = YES;
xmppRoster.autoAcceptKnownPresenceSubscriptionRequests = YES;
[stream addDelegate:self delegateQueue:dispatch_get_main_queue()];
XMPPJID* jid = [XMPPJID jidWithUser:#"username" domain:#"domain.com" resource:#"iOS"];
[stream setMyJID:jid];
[xmppRoster activate:stream];
[stream connectWithTimeout:XMPPStreamTimeoutNone error:&error]
and then in the xmppStreamDidConnect method I do this to authenticate
NSString *myPassword = #"password";
NSError *error = nil;
[stream authenticateWithPassword:myPassword error:&error]
When I am sending a message out I use this snippet:
MPPJID* recipient = [XMPPJID jidWithString:#"user#domain.com"];
XMPPMessage* message = [[XMPPMessage alloc] initWithType:#"chat" to:recipient];
[message addBody:#"hello world"];
[stream sendElement: message];
I'm thinking there is something simple I am missing that someone who has used this before will be able to point out to me right away. I'm ready to supply other info if necessary for solving this issue.
I simply needed to broadcast my presence, then I was able to receive messages.
I added these lines to the streamDidAuthenticate method
XMPPPresence *presence = [XMPPPresence presence];
[sender sendElement:presence];
I have gone through the XEP 0184 and have done following implementation.
If XMPP is connected and packet then is send then i set the status for each message as SENT (✔︎) if I don't get following callback.
-(void)xmppStream:(XMPPStream *)sender didReceiveError:(id)error
If i get the received status from XEP 0184 implemented in Objective C, I set the status as Delivered (✔︎✔︎)
RECV: < message xmlns="jabber:client" from="+122232322#wer.com/2323"
to="+3343232322#wer.com/2223" lang="" >< received
xmlns="urn:xmpp:receipts" id="avv-33343"/ >< /message >
But my question is how to show the SEEN status for each message as readh XMPP 0079 that is Advanced Messaging protocol is doing this. But I could not find in Objective C.
Can anyone please help? If my direction is correct and I am missing something could you let me know?
A code snippet guidance would be much appreciated.
Here is my implementation.
Using the stack documentation help I have added the following lines to get the delivery receipts.
XMPPMessageDeliveryReceipts* xmppMessageDeliveryReceipts = [[XMPPMessageDeliveryReceipts alloc] initWithDispatchQueue:dispatch_get_main_queue()];
xmppMessageDeliveryReceipts.autoSendMessageDeliveryReceipts = YES;
xmppMessageDeliveryReceipts.autoSendMessageDeliveryRequests = YES;
[xmppMessageDeliveryReceipts activate:self.xmppStream];
Now due to this I get the following response for the send and RECV xml.
SEND: 111111111 for avv-33343 Id message.
RECV: < message xmlns="jabber:client" from="+122232322#wer.com/2323"
to="+3343232322#wer.com/2223" lang="" >< received
xmlns="urn:xmpp:receipts" id="avv-33343"/ >< /message >
But this is just giving me info that the message is delivered but how to send the SEEN receipts like above to intimate the sender that the other end user have acknowledged + SEEN the message.
Something like this ... RECV: < seen xmlns="urn:xmpp:receipts" id="222-4444"/ >
For seen status use same functionality as send a normal message with same id which message received and you want to mark seen on Sender device,
When on sender device receive a static message #"to#fromSeen" with same message id for sent/delivered message, When receiver get exist msg id already in db then your purpose resolve .
Code for send seen status
NSString *bodymessageString = [NSString stringWithFormat:#"to#fromSeen"];
NSString *str_loginUser = [NSString stringWithFormat:#"%##%#", [[NSUserDefaults standardUserDefaults]valueForKey:#"mobile"],kXMPPServer ];
NSString *str_OtherUser = [NSString stringWithFormat:#"%##%#",str_OtherUserRegName,kXMPPServer];
NSXMLElement *body = [NSXMLElement elementWithName:#"body"];
[body setStringValue:bodymessageString];
NSXMLElement *message = [NSXMLElement elementWithName:#"message"];
[message addAttributeWithName:#"type" stringValue:#"chat"];
[message addAttributeWithName:#"from" stringValue:str_loginUser];
// [[[delegate xmppStream] myJID] bare]
[message addAttributeWithName:#"to" stringValue:str_OtherUser];
// NSString *messageID= [XMPPStream generateUUID];
[message addAttributeWithName:#"id" stringValue:str_msgID];
// NSXMLElement *request = [NSXMLElement elementWithName:#"request" xmlns:#"urn:xmpp:receipts"];
// [message addChild:request];
[message addChild:body];
[[delegate xmppStream] sendElement:message];
[ChatData GetUpdateToDatabase:str_msgID :#"Seen"];
Code for check message status in appdelegate file
if ([message isChatMessageWithBody])
{
if ([msg isEqualToString:#"to#fromSeen"])
{
BOOL is_Exist;
is_Exist = [ChatData GetAllReadyAvailable :message.elementID];
if (is_Exist == YES)
{
NSString *str_status = [ChatData getstatusChatBy:message.elementID];
if (![str_status isEqualToString:#"Seen"])
{
[ChatData GetUpdateToDatabase:message.elementID :#"Seen"];
}
}
}
else
{
BOOL is_Exist;
is_Exist = [ChatData GetAllReadyAvailable :message.elementID];
if (is_Exist == NO)
{
// Store message in DB
}
}
}
else if ([message hasReceiptResponse])
{
}
else if([message isErrorMessage])
{}
I am developing a chat system in both iOS. The chat server which I am using is ejabbered server. I am using Robbiehanson xmppframework for iOS chat client.
The issue which I am facing is that I am not able to establish a proper xmppstream between the chat client and the server. The xmppstream state is in STATE_XMPP_REGISTERING. This holds a value of 8. Due to this,when I try to authenticate the just created registered user, I am encountering an exception
"Error authenticating: Error Domain=XMPPStreamErrorDomain Code=1 "Please wait until the stream is connected." UserInfo=0x166c1e30 {NSLocalizedDescription=Please wait until the stream is connected.}
But surprisingly, I am able to register a user using a password. When I try to authenticate the user, I am encountering this exception due to which the registered user is not able to appear ONLINE.
I am using ConnectWithTimeOut to connect the xmppstream to the server
NSString *myPassword = #"password";
if (myJID == nil || myPassword == nil) {
return NO;
}
[xmppStream setMyJID:[XMPPJID jidWithString:myJID]];
password = myPassword;
NSError *error = nil;
if (![xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:&error])
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error connecting"
message:#"See console for error details."
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];
DDLogError(#"Error connecting: %#", error);
return NO;
}
Using this above code, I am able to establish a connection to the server.
Once the connectton is established, xmppStreamDidConnect is invoked.
when I checked the status of the XMPPStream, I am seeing the stream is connected.
Below is the code.
- (void)xmppStreamDidConnect:(XMPPStream *)sender
{
if ([xmppStream isDisconnected]){
NSLog(#"Is DisConnected");
[self connect];
}
if ([xmppStream isConnecting]){
NSLog(#"Is Connecting");
}
if ([xmppStream isConnecting]){
NSLog(#"Is Connecting");
}
if ([xmppStream isConnected]){
NSLog(#"Is Connected");
}
NSError *error = nil;
if (![[self xmppStream] registerWithPassword:#"password" error:&error]) {
NSLog(#"Registration error: %#", error);
}
if (![[self xmppStream] authenticateWithPassword:password error:&error])
{
DDLogError(#"Error authenticating: %#", error);
}else{
[self goOnline];
XMPPPresence *presence = [XMPPPresence presenceWithType:#"available"];
[sender sendElement:presence];
}
As per the above code, a user is registered and here comes the issue. When I try to authenticate the user, using authenticateWithPassword:password
XMPPLogTrace();
// The given password parameter could be mutable
NSString *password = [inPassword copy];
__block BOOL result = YES;
__block NSError *err = nil;
dispatch_block_t block = ^{ #autoreleasepool {
if (state != STATE_XMPP_CONNECTED)
{
NSString *errMsg = #"Please wait until the stream is connected.";
NSDictionary *info = [NSDictionary dictionaryWithObject:errMsg forKey:NSLocalizedDescriptionKey];
err = [NSError errorWithDomain:XMPPStreamErrorDomain code:XMPPStreamInvalidState userInfo:info];
result = NO;
return_from_block;
}
if (myJID_setByClient == nil)
{
NSString *errMsg = #"You must set myJID before calling authenticate:error:.";
NSDictionary *info = [NSDictionary dictionaryWithObject:errMsg forKey:NSLocalizedDescriptionKey];
err = [NSError errorWithDomain:XMPPStreamErrorDomain code:XMPPStreamInvalidProperty userInfo:info];
result = NO;
return_from_block;
}
the code below gets executed. But when I check the status of the xmppstream when I enter this delegate, I am seeing it in status 8 (which is STATE_XMPP_REGISTERING) though the user is successfully registered. This status makes to return a NO and hence the registered user is not appearing online.
Could anyone please help me in resolving this issue. I tried a lot of ways. But not able to progress.
Why I am not able to move to the next status and ultimately to status 12 before the authenticatewithpassword is invoked. Am I missing any intermediate steps after establishing a connection and successful registration. In nutshell, why the stream state stops at 8. and not going forward to
STATE_XMPP_AUTH,STATE_XMPP_BINDING,STATE_XMPP_START_SESSION, STATE_XMPP_CONNECTED, before getting into authenticatewithpassword
Logs for more info.
2014-05-30 07:40:20:995 konnectlinks[3249:8403] SEND: <?xml version='1.0'?>
2014-05-30 07:40:20:996 konnectlinks[3249:8403] SEND: <stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' to='localhost'>
2014-05-30 07:40:21.246 konnectlinks[3249:60b] dhaval is here
2014-05-30 07:40:21:608 konnectlinks[3249:4717] RECV: <stream:stream xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams" id="114321716" from="localhost" version="1.0" stream1:lang="en"/>
2014-05-30 07:40:21:609 konnectlinks[3249:8403] RECV: <stream:features xmlns:stream="http://etherx.jabber.org/streams"><starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>SCRAM-SHA-1</mechanism><mechanism>DIGEST-MD5</mechanism><mechanism>PLAIN</mechanism></mechanisms><c xmlns="http://jabber.org/protocol/caps" hash="sha-1" node="http://www.process-one.net/en/ejabberd/" ver="9DVbXp9C/vTyB5mLfy7wktk5Pfs="/><register xmlns="http://jabber.org/features/iq-register"/></stream:features>
2014-05-30 07:40:21.610 konnectlinks[3249:8403] -[XMPPReconnect xmppStreamDidConnect:]
2014-05-30 07:41:01.558 konnectlinks[3249:60b] Is Connected
2014-05-30 07:41:01.561 konnectlinks[3249:8403] -[XMPPReconnect setMultipleReachabilityChanges:]
2014-05-30 07:41:14.073 konnectlinks[3249:8403] -[XMPPReconnect setManuallyStarted:]
2014-05-30 07:41:14.076 konnectlinks[3249:8403] -[XMPPReconnect teardownReconnectTimer]
2014-05-30 07:41:14:076 konnectlinks[3249:60b] SEND: <iq type="set"><query xmlns="jabber:iq:register"><username>timop</username><password>password</password></query></iq>
2014-05-30 07:41:14.077 konnectlinks[3249:8403] -[XMPPReconnect teardownNetworkMonitoring]
2014-05-30 07:42:07:428 konnectlinks[3249:860b] RECV: <iq xmlns="jabber:client" from="localhost" type="result"><query xmlns="jabber:iq:register"><username>timop</username><password>password</password></query></iq>
2014-05-30 07:42:10:312 konnectlinks[3249:60b] Error authenticating: Error Domain=XMPPStreamErrorDomain Code=1 "Please wait until the stream is connected." UserInfo=0x166c1e30 {NSLocalizedDescription=Please wait until the stream is connected.}
I am sure someone would have encountered the issue.
Please help me in resolving this issue. Advance thanks for your time and help
I reviewed the code seems its right , Make sure the username and password you send it must be correct.
If nothing goes right then contact with your server/web team regarding this or try to connect with creating new user
I have a Problem with the XMPP-Framework for iOS. Every Time I fire registerWithPassword Method i get an Error:
"Error Domain=XMPPStreamErrorDomain Code=1 "Please wait until the
stream is connected." UserInfo=0xad7c300
{NSLocalizedDescription=Please wait until the stream is connected.} "
I do the following steps in my Code:
-(void)createUserWithUsername:(NSString*)name andPW:(NSString*)pw{
[self setupStream];
NSLog(#"name: %# ",name);
NSString *nameFor = name;
[self disconnect];
NSString *jidBenutzer = [NSString stringWithFormat:#"%##my-Server.com",nameFor];
NSError *error = nil;
NSError * err = nil;
NSLog(#"jabberid : %#",jidBenutzer);
XMPPJID *jid = [XMPPJID jidWithString:jidBenutzer];
self.xmppStream.myJID = jid;
[[self xmppStream] registerWithPassword:pw error:&err];
NSLog(#"Connection: %#",error);
NSLog(#"Register: %#",err);
}
I hope you can help me !
From your example code, I do not see any call to:
[xmppStream connect:&error]
From the error message, you are actually not connected.
Make sure you correctly call the connect method and that you are processing the error accordingly.
/**
* This method attempts to register a new user on the server using the given username and password.
* The result of this action will be returned via the delegate methods.
*
* If the XMPPStream is not connected, or the server doesn't support in-band registration, this method does nothing.
**/
This is the below.
- (BOOL)registerWithPassword:(NSString *)password error:(NSError **)errPtr
The method's instructions . You will find that before you use this method , you have to connecting the server.
I can' not find below.
[xmppStream connect:&error]
I use the this.
NSError *error;
NSString *tjid = [[NSString alloc] initWithFormat:#"anonymous#%#", serverName];
isRegister = YES;
[xmppStream setMyJID:[XMPPJID jidWithString:tjid]];
[xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:&error]
Please make sure your openfire server is turned on from your system preferences.
It is a late answer but still for any new developer like me: You have to login anonymously before registration: For example you are login with yourname#yourserver and your password try to login with unknown#yourserver and for password put nothing. So it will connect the stream but will not authenticate this is required for registration.
The stream should be connected but not be authenticated.