STOMP Websocket sometimes doesn't response - ios

I have a service using STOMP Websocket, I use WebsocketStompKit library
https://github.com/rguldener/WebsocketStompKit
NSURL *websocketUrl = [NSURL urlWithString:#"ws://xxx/websocket"];
STOMPClient *client = [[STOMPClient alloc] initWithURL:websocketUrl websocketHeaders:nil useHeartbeat:NO];
[self.client connectWithHeaders:nil completionHandler:^(STOMPFrame *connectedFrame, NSError *error) {
NSString *status = [Utils getStringIgnoreNull:connectedFrame.command];
if ([status isEqualToString:#"CONNECTED"]) {
NSLog(#"-------Connected to socket server!");
[self subscribe];
}
}];
I followed the instructions to setup STOMPClient, it works ok.
But sometime, it doesn't run to completionHander block, I waited a long time but it still don't response anything. My internet connection is very fine.
So anyone know the solution? Or can you give me another library to do this.
Thank so much.

As it turned out in this and this Github issue conversations, the problem was on the server side. If anyone comes here looking for help, I suggest going through these libraries issue pages and trying to match your problem, or contact the creators of Jetfire and Starscream (if you are implementing them) because they are very friendly and do answer your upgrade/new feature issues pretty quickly!

Related

How to use Signalr in iOS?

I have planned to use SignalR for my iOS application and searched for several hours to find a better solution but unfortunately I was not able to find a better solution for it.
Some of them where suggesting SignalR-ObjC for using SignalR in iOS but while I tried a sample with it, there were lot of issues on using SignalR-ObjC.
I'm looking forward to hear some third party plugins which makes SignalR integration possible at iOS.
Kindly advice me on how to use signalr for iOS application.
Note: Just as an additional information I'm providing the errors that I have struggled with SignalR-ObjC. If the errors are fixable then I will go ahead using the SignalR-ObjC for now.
The issues are: None of my clients are not getting invoked by server method call but SRConnectionDidOpen was getting invoked everytime.
I have mentioned by code below, kindly review it and let me know if I had done anything wrong with my code as I'm a beginner to Objective C.
hub = [connection createHubProxy:#"myHub"];
[hub on:#"addMessage" perform:self selector:#selector(addMessage:)];
connection.started = ^{
NSLog(#"started");
};
connection.received = ^(NSString * data) {
NSLog(#"%#",data);
};
[connection setDelegate:self];
[connection start];
}
- (void)addMessage:(NSString *)message{ // Print the message when it comes in
NSLog(#"message");
}
- (void)SRConnectionDidOpen:(SRConnection *)connection
{
[hub on:#"addMessage" perform:self selector:#selector(addMessage:)];
}
Thanks in advance.

NSURLConnection always failing after restarting app

I realize this is a vague question, but I'm wondering if anyone else has observed this. Here is my code for calling the NSURLConnection
// Get data from server
NSString *host = #"www.hostname.com";
NSString *urlString = [NSString stringWithFormat:#"/theRestOfTheURL"];
NSURL *url = [[NSURL alloc] initWithScheme:#"http" host:host path:urlString];
DLog(#"URL is %#", url);
// Create the NSMutableData to hold the received data.
// receivedData is an instance variable declared elsewhere.
receivedData_ = [[NSMutableData data] retain];
NSURLRequest *theRequest=[NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:15.0];
// create the connection with the request
// and start loading the data
self.powerPlantDataConnection = [[[NSURLConnection alloc] initWithRequest:theRequest delegate:self] autorelease];
[url release];
When I first load the app it works fine, and I can call it repeatedly without any problem. But if I close the app and reopen it, the
(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
delegate method gets called every time, with a request timed out error message. I have two different view controllers where I am making calls to two different URLS, and both of them fail every time after closing and reopening the app.
Can anyone think of any reason why this might be happening? I'm not sure where to start looking. What could be the cause of a request timed out error? There should be nothing wrong with the request since it works when I first run the app.
Edited to add that it seems I only have this problem on my device, not on the simulator.
Wish you had shared some chrash log(especially with clear definition like
[error localizedDescription] class method..)
As you have said it is going to timeout(your request). and since your way of creating the objects is too messy, you make the work bigger for your system. I suggest using GCD when downloading data and especially in situations like yours, having different interfaces and urls..
A suggestion
You can create your url object like this:
NSURL *url = [NSURL urlWithString:[NSString stringWithFormat:#"http://%#/%#?key1=%#&key2=%#", yourDomain, targetFile, value1, value2]];
I switched over to using ASIHTTPRequest, which improved things but I would still get stuck in situations where I was getting timed out errors every time I tried to refresh. I looked and asked around, and eventually found that disabling calls to TestFlight solved my issue. More information here:
ASIHTTPRequest request times out
and here:
github.com/pokeb/asi-http-request/issues/320

IOS: Using stringWithContentsOfURL when network is unavailable

In this code poll from within my app for a reachable network
("http://soxxx9.cafe24.com/event.php")
NSString * szURL =[NSString stringWithFormat:#"http://soxxx9.cafe24.com/event.php"];
NSURL *url = [NSURL URLWithString:[szURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding ]];
NSString *strData;
while(1)
{
NSError *error = nil;
strData = [NSString stringWithContentsOfURL:url
encoding:NSUTF8StringEncoding
error:&error];
if(!error)
break;
//String data is not owned by me, no need to release
}
If you have a better way, please teach me.
This code seems to be heavily power consuming when network is out : you'll try million times to download something that is unreachable...
Have a look at the Reachability class, provided by Apple (http://developer.apple.com/library/ios/#samplecode/Reachability/Introduction/Intro.html). You'll find ARCified versions on gitHub (https://github.com/tonymillion/Reachability for example).
The idea is to register for notifications about the network reachability.
So, in your code :
Check network resource availability before retrieving the string you want.
If this is available, use your code WITHOUT the while(TRUE)
Check your string for any error while retrieving it client side = in your code
If the network is not available, you'll have to inform the user that network is unreachable, and register for reachability notifications to retrieve your string as soon as it is reachable again for example.
You should a class to handle the connection for you. This way you have more control of what's going on with it. MKNetworkKit is a solution, you can check it here.

What are alternatives to NSURLConnection for chunked transfer encoding

I've checked for other questions relevant to this, but the only answer is "Use ASIHTTPRequest" as this is no longer being developed I wanted to ask what alternatives people are using, whilst working on our SDK I came across a lot of strange behaviour in NSURLConnection when receiving data from the server.
We tracked it down to the fact that NSURLConnection doesn't deal well with responses in chunked-encoding. Or at least so we read in this question here NSURLConnection and "chunked" transfer-coding
Some developers we were talking to say it gets better in iOS 5, we need to make sure that our SDK is backwards compatible with iOS 4.3 at least.
I want to confirm this is infact an issue in NSURLConnection, and how people are dealing with it.
All the alternatives I've found so far are based off of NSURLConnection and I'm assuming as such will have the same flaw. ASIHTTPRequest did in fact work because it's based a little lower than NSURLConnection, but were looking for alternatives in the knowledge it's no longer supported.
A list of other libraries looked at are:
Restkit,
ShareKit,
LRResty,
AFNetworking,
TTURLRequest
I'm aware there are similar questions here Is RESTKit a good replacement for ASIHTTPRequest? and here ASIHTTPRequest alternative But both of the solutions are based off NSURLConnection.
EDIT: I noticed I pointed to the wrong question at the start of my post, so thats updated. It points to a thread from 2008, and i've seen similar ones but none that are recent.
Chunked transfers are supported by NSURLConnection. I use them.
Define some props:
NSMutableData * responseData;
NSURLConnection * connection;
Establish a connection
NSURL *url = [NSURL URLWithString:#"...."];
self.responseData = [[NSMutableData alloc] initWithLength:0] ;
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
self.connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
Register your callback method for connection established
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
// You may have received an HTTP 200 here, or not...
[responseData setLength:0];
}
Register your callback method for "chunk received"
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
NSString* aStr = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
NSLog(#"This is my first chunk %#", aStr);
}
Register your "connection finished" callback:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[connection release];
}
And finally, register you "connection failed" callback:
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
NSLog(#"Something went wrong...");
}
Just to chime in for the next person that gets here and still can't get NSURLConnection to work with chunk encoded data.
NSURLConnection will work with chunked encoding, but has non-disclosed internal behaviour such that it will buffer first 512 bytes before it opens the connection and let anything through IF Content-Type in the response header is "text/html", or "application/octet-stream". This pertains to iOS7 at least.
However it doesn't buffer the response if Content-Type is set to "text/json". So, whoever can't get chunked encoded NSURLConnection responses to work (i.e. callbacks aren't called) should check the response header and change it on the server to "text/json" if it doesn't break application behaviour in some other way.
There aren't any alternatives I'm aware of.
All the other libraries are built on top of NSURLConnection. Though you could use one of the non-iOS libraries, eg. libcurl.
ASIHTTPRequest is the only library I'm aware of that's built on top of the CFNetworking layer instead. This was (perhaps indirectly) the main reason the original developer stopped working on it - because it doesn't use NSURLConnection it has a lot of code.
It's probably not strictly correct to say that ASIHTTPRequest is no longer supported. It is true that the original developer no longer works on it, but if you look at the github commits you'll see it is still being worked on by other people. A lot of people still use it, for various reasons, myself included.
Having said all that, to go back to the problem you have: I'm not sure a 3 year old thread is necessarily a definitive reference to prove that a 1 year old release (ie. iOS 4.3) of NSURLConnection doesn't support chunked transfers. Chunked transfers are used so much on the web that it seems highly unlikely it would have a problem this large and obvious. It's possible there is something very particular to the server that you're using that is causing the issue.

How to purge / flush cache of NSString

Currently I am doing simple tests of my app (written in xCode for MAC OS X) and I noticed that there are some issues when it comes to getting data from internet. So I am requesting some text data:
NSString *dataFromInternet = [[NSString alloc] initWithContentsOfURL:url
usedEncoding:&encoding
error:&error];
Now:
If internet works then everything is awesome.
If internet disconnected then I am getting error in "error" however "dataFromInternet" still returns the very same data as if there was internet connect
If I request data (above code) while internet disconnected and then connect internet and request data once again, I am still getting error as if internet doesn't work!
I don't understand this behavior and what is going on. I can only guess there is some caching mechanism and I don't now how to fix it.
Please explain this ( #2 & #3 ) odd behavior and how to fix it.
Thank you.
Okay, so after sometime roaming around internet and trying to find answer to my question, here is what I came up with:
NSString *dataFromInternet = [[NSString alloc] initWithContentsOfURL:url
usedEncoding:&encoding
error:&error];
Above code does seem to use cache. In order to get data from internet and not to have all issues that are posted in the question, you have to use different object.
NSData* data = [[NSData alloc] initWithContentsOfURL:url options:NSUncachedRead error:&error];
NSString *dataFromInternet = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
What is happening in above sample code? You get data from internet almost the same way as you would with NSString except you specify following: "options:NSUncachedRead" - meaning that it will not cache the data and read always the latest and greatest - under condition that internet works.
Once you obtained data you can convert it into NSString if desirable. I needed NSString so I converted it back to what I want. Otherwise all of issue in original post are solved!
I can turn off airport on my mac and no data will be received and as soon as I turn on airport, data is flowing again. Very simple and works great for me.
Thank you.
So I'm not able to repro this. With this code:
NSError *error = nil;
NSStringEncoding encoding = 12345678; // known bad value
NSString *test = [[NSString alloc] initWithContentsOfURL:[NSURL URLWithString:#"http://www.example.com/non-existant-page.html"] usedEncoding:&encoding error:&error];
if (test == nil) {
NSLog(#"didnt work:%#, enc=%d, error:%#",test, encoding, error);
} else {
NSLog(#"worked:%#, enc=%d, error:%#", test, encoding, error);
}
... and without internet, I get this:
2011-08-28 22:30:45.482 test[48578:207] didnt work:(null), enc=12345678, error:Error Domain=NSCocoaErrorDomain Code=256 "The operation couldn’t be completed. (Cocoa error 256.)" UserInfo=0x5b09280 {NSURL=http://www.example.com/non-existant-page.html}
I also ran this after doing it with internet to confirm that it wasn't being cached (it isn't), so I don't see how you could have gotten a result. Can you give us more of the code that you used?

Resources