WCF: WS-Dual binding or basichttp binding to stream file in chunks

790 views Asked by At

I'm currently developing service in which client communicate with server by sending xml files with messages. In order to improve reliability of messaging (client will be using low quality limited bandswitch mobile internet) I chunks these message in smaller portions of 64 or 128 Kb size, and send them with transfer="streamed" in BasicHttp binding.

Now, I have a problem: server should report to client, if he succesfully received a chunk or not, so after f.e 5 chunks failed to transfer, the transfer process will be cancelled and postponed to be tried later, and to keep track of which chunks are received and which are not.

I'm thinking about using callback mechanism to communicate client, so server will invoke callback method ChunkReceived in it's [OperationContract], when it saves chunk to the file on the server-side, but, correct me if I'm wrong, but callback only works with WS Dual http binding, and isn't supported in basichttp binding. But streamed transfer isn't supported in WS Dual binding.

So is it ok for me to switch to WS Dual binding and use transfer="buffered" (considering chunk size is relatively small) - won't that hurt reliability of the transfer? Or maybe I can somehow communicate with client in basic http binding, maybe by returning some kind of response message, i.e.

    [OperationContract]
    ServerResponse SendChunk (Chunk chunk);

where ServerResponse will hold some enum or bool flag to tell the client if the SendChunk operation is ok. But then I will have to keep some kind of array on both client and server side to keep track of all the chunks status. I'm just not sure what's the best pattern to use there. Any advice would be highly appreciated.

1

There are 1 answers

1
Varius On

We had similar problem in our application - low bandwidth and many disconnects/timeouts. We have smaller messages, so we didn't split them, but the solution should work to for chunks too. We've created Repeater on client. This proven to be reliable solution - it works well on clients with slow, poor connections(like GPRS - being on the move disconnected often). Also client won't get timeout errors if server slows down due to high load. Here is modified version, with chunks

Client:

1. Client sends Chunk#1, with pretty short timeout time

2. Is there OK response:

   2A. Yes - proceed to next chunk

       3. Was that last chunk?

          3A. Yes - process reponse

          3B. No - send next chunk

   2B. No - repeat current chunk

Server:

  1. Accept request

  2. Is Chunk repeated

    2A. Yes:

    1. Is final chunk:

      3A. Yes - check if response is ready, else wait(this propably will make client repeat)

      3B. No - send Ok reponse

    2B. No:

    1. Save request somewhere (list, dictionary etc.)

    2. Is this last chunk:

      5A. Yes - Process message, save Reponse, and send it to client

      5B. No - Send Ok Message