iPhone Jabber/XMPP client... "TURN Connection failed" - ios

I am trying to build a simple Jabber client.
I have downloaded this sample project, which uses xmpp-framework https://github.com/funkyboy/Building-a-Jabber-client-for-iOS
I am running it in the iOS Simulator. I have installed Openfire locally so that I can interact with a user logged into iChat.
Unfortunately the app only receives messages. It fails in sending messages giving the error "TURN Connection failed!".
This is the code attempting to connect:
- (void)viewDidLoad
{
[super viewDidLoad];
self.tView.delegate = self;
self.tView.dataSource = self;
[self.tView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
messages = [[NSMutableArray alloc ] init];
JabberClientAppDelegate *del = [self appDelegate];
del._messageDelegate = self;
[self.messageField becomeFirstResponder];
XMPPJID *jid = [XMPPJID jidWithString:#"user#server.local"];
NSLog(#"Attempting TURN connection to %#", jid);
TURNSocket *turnSocket = [[TURNSocket alloc] initWithStream:[self xmppStream] toJID:jid];
[turnSockets addObject:turnSocket];
[turnSocket startWithDelegate:self delegateQueue:dispatch_get_main_queue()];
[turnSocket release];
}
And those are the methods called on success/failure:
- (void)turnSocket:(TURNSocket *)sender didSucceed:(GCDAsyncSocket *)socket
{
NSLog(#"TURN Connection succeeded!");
NSLog(#"You now have a socket that you can use to send/receive data to/from the other person.");
[turnSockets removeObject:sender];
}
- (void)turnSocketDidFail:(TURNSocket *)sender
{
NSLog(#"TURN Connection failed!");
[turnSockets removeObject:sender];
}
Can anyone please help?
Thank you.

There is no reason to use TURN for normal messaging. TURN is required for media streaming only. Just use XMPPFramework. There are some good getting-started guides.
Next, use code of this nature to create and send stanzas:
XMPPMessage *msg = [XMPPMessage message];
[msg addAttributeWithName:#"type" stringValue:#"chat"];
[msg addAttributeWithName:#"to" stringValue:#"foo#example.com"];
NSXMLElement *body = [NSXMLElement elementWithName:#"body" stringValue:#"Hello"];
[msg addChild:body];
[[self xmppStream] sendElement:msg];
Note that msg is just a subclass of NSXMLElement, so you can modify the XML at will to craft the protocol you're going to send.

Related

Objective C: add contact to xmpp framework via app

I am doing Chat App. XMPP Framework, automatically fetch contacts from ejabbered server. I am unable to add contacts to ejabbered server through my app. For ex: If I login through iOS Client, Jitsi, there I can give add contact. That too immediately reflect in my app and ejabbered server automatically. I dont know how to add my phone book contacts to ejabbered via my app.
Kindly guide how to add contact through my app.
Coding
- (void)setupStream
{
XMPPJID jid = [XMPPJID jidWithString:[NSString stringWithFormat:#"%##localhost",
`addBuddyTextField.text]];
[appDelegate.xmppRoster addUser:jid withNickname:addBuddyTextField.text];
xmppStream = [[XMPPStream alloc] init];
xmppReconnect = [[XMPPReconnect alloc] init];
xmppRosterStorage = [[XMPPRosterCoreDataStorage alloc] init];
xmppRoster = [[XMPPRoster alloc] initWithRosterStorage:xmppRosterStorage];
xmppRoster.autoFetchRoster = YES;
xmppRoster.autoAcceptKnownPresenceSubscriptionRequests = YES;
}
For adding contacts first you need to send subscribe message to destination user (if destination user is registered to XMPP)
Send subscribe message
- (void) sendSubscribeMessageToUser:(NSString*)userID
{
XMPPJID* jbid= [XMPPJID jidWithString:userID];
XMPPPresence *presence = [XMPPPresence presenceWithType:#"subscribe" to:jbid];
[xmppStream sendElement:presence];
}
when destination user received subscribe message
/**
This fuction is called when other user state is changed
*/
- (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence
{
DDLogVerbose(#"%#: %# - %#", THIS_FILE, THIS_METHOD, [presence fromStr]);
NSString *presenceType = [presence type]; // online/offline
NSString *myUsername = [[sender myJID] user];
NSString *presenceFromUser = [[presence from] user];
NSString* presenceState= [presence status];
NSLog(#"%# is %# state %#",presenceFromUser,presenceType,presenceState);
if ([presenceType isEqualToString:#"subscribe"])
{
[xmppRoster subscribePresenceToUser:[presence from]];
}
else if ([presenceType isEqualToString:#"subscribed"])
{
[xmppRoster subscribePresenceToUser:[presence from]];
}
}
these functions will add automatically destination user to your contact list

Unable to implement Turn Socket for File transfer in iOS Using XMPP

I am using below code for creating turn Socket but every time it goes in turnSocketDidFail method so whats the wrong in the code , please help me out.
XMPPJID *JID = [XMPPJID jidWithString:#"9107#test.com/110s-Mac-mini"];
[TURNSocket setProxyCandidates:[NSArray arrayWithObjects:JID.domain, nil]];
TURNSocket *socket = [[TURNSocket alloc] initWithStream:[[NDAppDelegate shareAppDelegateInstance] xmppStream] toJID:JID];
[socket startWithDelegate:self delegateQueue:dispatch_get_main_queue()];
- (void)turnSocket:(TURNSocket *)sender didSucceed:(GCDAsyncSocket *)socket {
NSLog(#"TURN Connection succeeded!");
}
- (void)turnSocketDidFail:(TURNSocket *)sender {
NSLog(#"TURN Connection failed!");
}

Unable to connect iPhone device with the ejabberd server

I am new in iOS development and try to connect my iPhone device with the ejabberd server.I follow Xmpp.org document.And also I follow this "http://code.tutsplus.com/tutorials/building-a-jabber-client-for-ios-interface-setup--mobile-7188" document thoroughly.This is a great tutorial.This help me a lot a to setup a ejabberd server in my mac and able to connect to two different application(iMessage and Adium) through ejabberd server but I am facing some problem when I started iPhone application.
First I got XMPP importing error.but I solve it, after that app crash when I use [XMPPStream addDelegate: self delegateQueue:dispatch_get_main_queue() ] method.That time Compiler says "unrecognized selector sent".so I change it to [XMPPStream addDelegate:self ].Error removed.
And at last I got alert message which told me"Can't connect to server",and finally unable to connect to the server.
I want to test client-server connection locally,so I changed server address with my Mac Ip.but still unable to connect.
please help me....If possible please suggest me how to proceed further & any other document on XMPP.
Thanks a lot.
I call this connect function when application start.
- (BOOL)connect {
[self setupStream];
NSString *jabberID = [[NSUserDefaults standardUserDefaults]stringForKey:#"userID"];
NSString *myPassword =[[NSUserDefaults standardUserDefaults] stringForKey:#"userPassword"];
if (![xmppStream isDisconnected]) {
return YES;
}
if (jabberID == nil || myPassword == nil) {
return NO;
}
[xmppStream setMyJID:[XMPPJID jidWithString:jabberID]];
password = myPassword;
NSError *error = nil;
if (![xmppStream connect:&error]){
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error" message:[NSString stringWithFormat:#"Can't connect to server %#", [error localizedDescription]] delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[alertView show];
[alertView release];
return NO;
}
return YES;
}
- (void)setupStream {
xmppStream = [[[XMPPStream alloc] init] autorelease];
[xmppStream addDelegate:self];
//[xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
}
- (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence {
NSString *presenceType = [presence type]; // online/offline
NSString *myUsername = [[sender myJID] user];
NSString *presenceFromUser = [[presence from] user];
if (![presenceFromUser isEqualToString:myUsername]) {
if ([presenceType isEqualToString:#"available"]) {
[_chatDelegate newBuddyOnline:[NSString stringWithFormat:#"%##%#", presenceFromUser, #"MYSERVER"]];
} else if ([presenceType isEqualToString:#"unavailable"]) {
[_chatDelegate buddyWentOffline:[NSString stringWithFormat:#"%##%#", presenceFromUser, #"MYSERVER"]];
}
}
}
in the connect method try using these two lines also, if u are using ejabberd as mentioned in the tutorial
xmppStream.hostName = #"localhost";
xmppStream.hostPort=5222;
i was following the same tutorial and it worked for me after adding these lines..put breakpoints in the
- (void)xmppStreamDidConnect:(XMPPStream *)sender
delegate method to check if its connecting

File transfer using XMPPFramework

I am using xmpp framework for my iPhone chat Application. I can able to do text chat through xmpp framework.
- (void)viewDidLoad {
TURNSocket *turnSocket = [[TURNSocket alloc] initWithStream:[self xmppStream] toJID:jid];
[turnSockets addObject:turnSocket];
[turnSocket startWithDelegate:self delegateQueue:dispatch_get_main_queue()];
[turnSocket release];
}
- (void)turnSocket:(TURNSocket *)sender didSucceed:(GCDAsyncSocket *)socket {
NSLog(#"TURN Connection succeeded!");
NSLog(#"You now have a socket that you can use to send/receive data to/from the other person.");
[turnSockets removeObject:sender];
}
- (void)turnSocketDidFail:(TURNSocket *)sender {
NSLog(#"TURN Connection failed!");
[turnSockets removeObject:sender];
}
But want to transfer file through xmpp framework on openfire server and failed to establish TurnSocketConnection.

XMPPFramework - TURNSocket can't receive the data that sent by myself?

I used the openfire as the xmpp server, and want to transfer file via the Turnsocket.
The openfire (local) config:
xmpp.auth.anonymous true
xmpp.domain local
xmpp.enabled true
xmpp.externalip proxy.local, 192.168.1.101, 127.0.0.1
xmpp.proxy.enabled true
xmpp.proxy.port 7777
xmpp.proxy.transfer.required false
xmpp.server.socket.active true
xmpp.session.conflict.limit 0
xmpp.socket.ssl.active true
I tested the file transfer in the local environment, one user is logged in by Simulator (Sender), the other user is logged in by Device (iPod, receiver).
TURNSocket.m (both changed), change the proxy
+ (void)initialize {
...
proxyCandidates = [[NSMutableArray alloc] initWithObjects:#"local", nil];
...
}
Config both on sender and receiver
- (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq {
...
if ([TURNSocket isNewStartTURNRequest:iq]) {
NSLog(#"IS NEW TURN request Receive.. TURNSocket..................");
TURNSocket *turnSocket = [[TURNSocket alloc] initWithStream:xmppStream incomingTURNRequest:iq];
[turnSockets addObject:turnSocket];
[turnSocket startWithDelegate:self delegateQueue:dispatch_get_main_queue()];
[turnSocket release];
}
return YES;
}
Setup and call TURNSocket (Sender)
TURNSocket *turnSocket = [[TURNSocket alloc] initWithStream:[self xmppStream] toJID:user.primaryResource.jid];
[turnSockets addObject:turnSocket];
[turnSocket startWithDelegate:self delegateQueue:dispatch_get_main_queue()];
[turnSocket release];
didSucceed called both (sender and receiver)
- (void)turnSocket:(TURNSocket *)sender didSucceed:(GCDAsyncSocket *)socket {
}
Send a file? on sender
- (void)turnSocket:(TURNSocket *)sender didSucceed:(GCDAsyncSocket *)socket {
NSData *dataF = [[NSData alloc] initWithContentsOfFile:
[[NSBundle mainBundle] pathForResource:#"a1" ofType:#"png"]];
[socket writeData:dataF withTimeout:60.0f tag:0];
}
OR: Received data here? (Receiver)
- (void)turnSocket:(TURNSocket *)sender didSucceed:(GCDAsyncSocket *)socket {
NSData *dataF = [[NSData alloc] init];
[socket readDataToData:dataF withTimeout:30.0 tag:0];
NSLog(#"dataF: %d", [dataF length]); // dataF: 0
}
Does anyone know what's the problem?
Thanks very much!
To set an external ip address, you need to use xmpp.proxy.externalip rather than xmpp.externalip

Resources