3

Just wondering, if there's existed class of framework, which would deal with request queuing.

When request is sent, is should be added to the queue. If something is wrong (no internet), request should be stored, and tried to be sent again later.

Meanwhile, more requests can be created. If there's still no network, all new requests should be stored in the queue, and sent again while network would return.

Going to make same functional, wondering if it is already implemented.

EDIT1: I'm using HttpWebRequest for Posting/Getting json data to/from server.

EDIT2: Sample case:

  1. User press Button1. First request is sent, added to queue, (internet is avaivable), app got answer, request is removed from the queue.

  2. User press Button2. Second request is sent, added to queue, no internet connection -> request is stored in the queue.

  3. User press Button3. Third request is going to be send, but as queue is not empty, it is just stored to the queue. Request2 tries to be delivered, but still no connection.

  4. Some time later, connection is established again, so Request2 succeeded, removed from the queue, then Request3 also succeeded and removed from the queue.

  5. What is important - it should be resistant to tombstoning. If phone goes to sleep before calling request, it should be stored. Is request is in progress, it should be cancelled (or exactly this message should not be stored).

EDIT3: For avoiding delivery exceptions, i'm using this wrapper:

public async Task<string> GetAsync(string url)
    {
        var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
        httpWebRequest.Method = HttpMethod.Get;
        httpWebRequest.Accept = "application/json";

        try
        {
            var response = (HttpWebResponse)await httpWebRequest.GetResponseAsync();

            if (response == null || response.StatusCode != HttpStatusCode.OK)
                return String.Empty;

            string data;

            using (var responseStream = response.GetResponseStream())
            {
                using (var postStreamReader = new StreamReader(responseStream))
                {
                    data = await postStreamReader.ReadToEndAsync();
                    postStreamReader.Close();
                }
                responseStream.Close();
            }

            return data ?? String.Empty;
        }
        catch (Exception ex)
        {
            return String.Empty;
        }
    }

It returns String.Empty if there's any exceptions, otherwise, it returns server answer's string. What i need now is a pattern, which would guarantee that call was successful (result is not empty), otherwise, keep it in queue (to keep order) and would try to raise call again, until it would be delivered.

EDIT4: for now, i'm considering having a queue in a semaphore, and call it when i need to force pushing. Any thoughts if it would work fine?

Vitalii Vasylenko
  • 4,776
  • 5
  • 40
  • 64
  • Why downvoting? I don't think that it is unnecessary or useless functional, is it? – Vitalii Vasylenko Jun 01 '13 at 23:17
  • What does guaranteed request delivery mean? What about the responses to the requests surely they are important? A Http Request is not just fire and forget. – Dave Hillier Jun 01 '13 at 23:26
  • @DaveHillier Well, that means that if there would be some internet troubles, request would be stored and delivered later. Yep, i should know, if my request was delivered to the server successfully. – Vitalii Vasylenko Jun 01 '13 at 23:28
  • A HTTP request is typically something like fetching a web page. What do you want to do with the response to that request? – Dave Hillier Jun 01 '13 at 23:30
  • I'm using HttpWebRequest for Posting/Getting json data to/from server. – Vitalii Vasylenko Jun 01 '13 at 23:32
  • Ok, I get that - but what happens to your app when your get fails? Does queuing make sense? Or do you just want to pause the app until you regain connectivity. – Dave Hillier Jun 01 '13 at 23:35
  • @DaveHillier Nope, no pauses. I want app to be still responsible to user's input, but all requests that user sends, should be 100% delivered. – Vitalii Vasylenko Jun 01 '13 at 23:37
  • @DaveHillier Added sample to the post. – Vitalii Vasylenko Jun 01 '13 at 23:43
  • Perhaps I'm missing something but can't this be solved with a simple producer/consumer queue like `BlockingCollection` and wrapping `GetAsync()` with something that loops calls to `GetAsync()` until a valid response is received? – Mills Oct 22 '13 at 05:55
  • @Mills As far as i found, the major problem is with tombstoning. Say, i have several requests in a queue, then phone goes to tombstoned state. If i'd just save queue to the file, current call can be at the final stage, so it would be fired 2 times (1st during tombstoning, but it would be also stored to file, so 2nd time it would be fired when app would be reactivated). – Vitalii Vasylenko Oct 22 '13 at 05:59
  • And thanks for the tip, i'll take a look at BlockingCollection. – Vitalii Vasylenko Oct 22 '13 at 06:01

4 Answers4

3

I made simple example which uses Queue object to hold list of requested URLs. Basically it just makes requests one by one. And always sends a Completed event when the request is finished. It is then up to Completed event's handler to handle page that is returned or error conditions that are returned.

Also, there's tombstoning support. Basically it saves the queue to isolated storage when Application_Deactivated or Application_Closing callbacks are called. And loads it in the app constructor/Application_Activated function if app returns from tombstoned stage. I hope this gets you started.

http://www.mediafire.com/download/cncuwx1kttehv8y/PhoneApp15.zip

Nearga
  • 106
  • 3
2

Sorry I don't have time to make a very full answer, but the System.Threading.Tasks.Dataflow namespace may have some very helpful things for you.

Elliot
  • 2,002
  • 1
  • 20
  • 20
1

Take a look at SPA (Single Page Applications) which run on the client side using AJAX requests. Your server logic would shift from handling all the business logic to simply feeding the client data with the business logic done on the client in JavaScript. This allows an app to function without server data coming in. You can then handle what you want it to do in the case of 404 errors, including trying again later. Get very familiar with JavaScript.

RyanJMcGowan
  • 1,485
  • 1
  • 15
  • 33
  • JavaScript is not a problem :) The problem is modifying server, what i really don't want to do. Nice note to consider in the future, but for now i should just find a solution, which would guarantee message delivery to/from the server. – Vitalii Vasylenko Jun 02 '13 at 09:09
0

This just popped up from memory. But not sure about if and how persistance is implemented. If messages needs to be delivered even after the a browser restart, you can implement that part in using local storage.

Stomp as a protocol can serve your needs. Nice tut here: http://blog.mayflower.de/2011-Message-Queues-for-web-applications-with-STOMP.html

Other options: Messagebus for jQuery

A full servicebus is perhaps a little bit overkill but to borrow some ideas it can give a headstart:

pServicebus Implemented serverside in C# and comes with JS-client

JS-client for MassTransit: MassTransit-JS

lboshuizen
  • 2,746
  • 17
  • 20