OK i have tried a lot of different methods for this. I want to call a JSON API,get its response, save the key values, then call it again with different parameters. Most recently, I tried calling the URL method in a for loop, posting an NSNotification in connectionDidFinishLoading: and NSLogging values in observer when the notification gets posted. But its only logging the values of the final call multiple times.
I use this for the connection initialisation...
eventConnection=[[NSURLConnection alloc]initWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlString]] delegate:self startImmediately:NO];
[eventConnection scheduleInRunLoop: [NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[eventConnection start];
This is the delegate method...
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSNotification *eventNotification=[NSNotification notificationWithName:#"eventsFound" object:nil userInfo:responseDict];
[[NSNotificationQueue defaultQueue]enqueueNotification:eventNotification postingStyle:NSPostNow coalesceMask:NSNotificationCoalescingOnName forModes:nil];
}
Any suggestions as to how i can achieve this?
To effectively chain multiple NSURLConnection requests, you should not start them all at once (e.g., like you say "in a for loop").
Instead, start the first request; then, from the connectionDidFinishLoading start the second; then again, when connectionDidFinishLoading is executed again, start the third and so on.
This is just a sketch of how you could do it to help you find a good design for your app; one possibility is:
define a state machine that is responsible for firing the requests depending on the current state; (the state could be a simple integer representing the sequential step you have go to);
start the state machine: it will fire the first request;
when the request is done, connectionDidFinishLoading will signal the state machine, so that it moves to the next step;
at each step, the state machine fires the request corresponding to that step.
There are other design options possible, of course; which is the best will depend on your overall requirements and the kind of call flow you need.
set a counter and total number of requests to send. and in connection did finished loading, check that if counter is reached to total number of rquests to send else call the method again in which you was sending the data, and increment sent requests. if u use data from file. i.e. first write data to file wid a number and then read it when u want to send request, then it wud b great
Hum,
Did you try to use Libraries like AFNetworking, you can create asynch request and using blocks to handle answers.
You can use NSOPerationQueue or Block or thread for same. Call another function after finishing one.
Related
In Fiddler how can I slow down the response of a specific request only, while passing through the response from the server?
I'm aware I can simulate a slow speed for all requests - that's not what I want.
Using the AutoResponder with a specific rule forces me to choose what to respond with.
How can I use the "Latency" feature without modifying the response? Is this possible in Fiddler?
I understood your question that you want to delay either request or response time for a specific request.
You could do it with the FiddlerScript module by updating the oSession object.
onBeforeRequest
// Delay sends by 300ms per KB uploaded.
oSession["request-trickle-delay"] = "300";
onBeforeResponse
// Delay receives by 150ms per KB downloaded.
oSession["response-trickle-delay"] = "150";
You would also need to filter the correct request in the selected method.
Filtering
// Sample Rule: Break requests for URLs containing "/path/"
if (oSession.uriContains("/path/")) {
}
if (oSession.hostname == "some.hostname") {
}
if (oSession.url == "some.url") {
}
Additional info can be found here
Hope it helps
Rather than using the latency feature, you can enter *delay:5000 as the then respond with... command, instead of a file path.
I noticed that the rules are ignored with a blank response, so you can use the latency with a command/path of *action, which isn't a real action, but causes the rule to execute and the latency to take effect, in case you really want to use the Latency column.
I am looking into the Swift Vapor framework.
I am trying to create a controller class that maps data obtained on an SSL link to a third party system (an Asterisk PBX server..) into a response body that is sent over some time down to the client.
So I need to send received text lines (obtained separately on the SSL connection) as they get in, without waiting for a 'complete response' to be constructed.
Seeing this example:
return Response(status: .ok) { chunker in
for name in ["joe\n", "pam\n", "cheryl\n"] {
sleep(1)
try chunker.send(name)
}
try chunker.close()
}
I thought it might be the way to go.
But what I see connecting to the Vapor server is that the REST call waits for the loop to complete, before the three lines are received as result.
How can I obtain to have try chunker.send(name) send it's characters back the client without first waiting for the loop to complete?
In the real code the controller method can potentially keep an HTTP connection to the client open for a long time, sending Asterisk activity data to the client as soon as it is obtained. So each .send(name) should actually pass immediately data to the client, not waiting for the final .close() call.
Adding a try chunker.flush() did not produce any better result..
HTTP requests aren't really designed to work like that. Different browsers and clients will function differently depending on their implementations.
For instance, if you connect with telnet to the chunker example you pasted, you will see the data is sent every second. But Safari on the other hand will wait for the entire response before displaying.
If you want to send chunked data like this reliably, you should use a protocol like WebSockets that is designed for it.
in ASIHTTPRequest class
I debug - (void)main method of the NSOperation with wireshark . I want to find which method send data.
But i debug to the end of startRequest in main method of NSOperation. I can't grab any data.
Because the read stream opens a socket connection with the server specified by the myUrl parameter when the CFHTTP request was created, some amount of time must be allowed to pass before the stream is considered to be open. Opening the read stream also causes the request to be serialized and sent.
base the above document of apple about "Communicating with HTTP Servers"
the most chance to send data is the below code .But it don't. I can't find something in wireShark.
CFStreamClientContext ctxt = {0, self, NULL, NULL, NULL};
if (CFReadStreamSetClient((CFReadStreamRef)[self readStream], kNetworkEvents, ReadStreamClientCallBack, &ctxt)) {
if (CFReadStreamOpen((CFReadStreamRef)[self readStream])) {
streamSuccessfullyOpened = YES;
}
}
where send data ???? like socket send or sendto function.
[request startAsynchronous];
and
[request startSynchronous];
If your program is for command line, just use [request startSynchronous] in main, because if you use asynchronous request, the main thread continue, when main thread terminate, maybe asynchronous request do nothing.
I create an inputstream for ftp request as below:
ftpStream = CFReadStreamCreateWithFTPURL(NULL, (CFURLRef) url);
networkStream = (NSInputStream *) ftpStream;
[self.networkStream read:<#(uint8_t *)#> maxLength:<#(NSUInteger)#>]
when I read data, if the server is not able to be connected, the programme will be stucked at the third line above. Is there a method could stop the connection after some second which you can define? Or if some other method to deal with this?
Don't do a synchronous read. Instead, set a delegate on the stream object, schedule it on the run loop, and call -open. If you're on the main thread of an app, just return control back to the framework at this point and it will run the run loop for you. If you're on a background thread or writing a command-line tool, run the thread's run loop yourself. Your delegate will be called when there's data to be read.
To establish a timeout for the connection, you can schedule a timer on the run loop. Alternatively, if you're running the run loop yourself, you can just put a limit on how long you'll run it. If the time expires before the connection has been made, just close the stream.
I want to send a large amount of data to a server using NSURLConnection (and NSURLRequest). For this I create a bound pair of NSStreams (using CFStreamCreateBoundPair(...)). Then I pass the input stream to the NSURLRequest (-setHTTPBodyStream:) and schedule the output stream on the current run loop. When the run loop continues, I get the events to send data and the input stream sends this data to the server.
My problem is, that this only works when the data fits into the buffer between the paired streams. If the data is bigger, then somehow the input stream gets an event (I assume "bytes available") but the NSURLConnection has not yet opened the input stream. This results in an error message printed and the data is not being sent.
I tried to catch this in my -stream:handleEvent: method by simply returning if the input stream is not yet opened, but then my output stream gets a stream closed event (probably because I never sent data when I could).
So my question is: How to use a bound pair of streams with NSURLConnection correctly?
(If this matters: I'm developing on the iOS platform)
Any help is appreciated!
Cheers, Markus
Ok, I kind of fixed this by starting the upload delayed, so that it starts after the NSURLConnection had time to setup its input stream.
It's not what I call a clean solution though, since relying on -performSelector:withObject:afterDelay: seems a bit hacky.
So if anyone else has a solution to this, I'm still open for any suggestions.