WCF: привязка WS-Dual или привязка basichttp к потоковому файлу фрагментами

В настоящее время я разрабатываю сервис, в котором клиент общается с сервером, отправляя XML-файлы с сообщениями. Чтобы повысить надежность обмена сообщениями (клиент будет использовать низкокачественный мобильный интернет с ограниченной полосой пропускания), я разбиваю эти сообщения на более мелкие части размером 64 или 128 КБ и отправляю их с помощью transfer="streamed" в привязке BasicHttp.

Теперь у меня есть проблема: сервер должен сообщить клиенту, успешно ли он получил блок или нет, поэтому после того, как 5 блоков не удалось передать, процесс передачи будет отменен и отложен, чтобы попробовать позже, и отслеживать, какие чанки принимаются, а какие нет.

Я думаю об использовании механизма обратного вызова для связи с клиентом, поэтому сервер будет вызывать метод обратного вызова ChunkReceived в своем [OperationContract], когда он сохраняет фрагмент в файл на стороне сервера, но поправьте меня, если я ошибаюсь, но обратный вызов работает только с привязкой WS Dual http и не поддерживается при привязке basichttp. Но потоковая передача не поддерживается привязкой WS Dual.

Итак, могу ли я переключиться на двойную привязку WS и использовать transfer="buffered" (учитывая, что размер фрагмента относительно мал) - не повредит ли это надежности передачи? Или, может быть, я могу как-то общаться с клиентом в базовой привязке http, может быть, возвращая какое-то ответное сообщение, т.е.

    [OperationContract]
    ServerResponse SendChunk (Chunk chunk);

где ServerResponse будет содержать некоторый флаг enum или bool, чтобы сообщить клиенту, в порядке ли операция SendChunk. Но тогда мне придется хранить какой-то массив как на стороне клиента, так и на стороне сервера, чтобы отслеживать состояние всех фрагментов. Я просто не уверен, какой шаблон лучше всего использовать там. Любые советы будут высоко оценены.


person Dr.Strangelove    schedule 09.08.2012    source источник


Ответы (1)


У нас была аналогичная проблема в нашем приложении - низкая пропускная способность и много отключений/тайм-аутов. У нас есть сообщения меньшего размера, поэтому мы не разделяли их, но решение должно работать и для фрагментов. Мы создали Repeater на клиенте. Это решение зарекомендовало себя как надежное - оно хорошо работает на клиентах с медленным и плохим соединением (например, GPRS, когда соединение часто отключается в пути). Также клиент не будет получать ошибки тайм-аута, если сервер замедляется из-за высокой нагрузки. Вот модифицированная версия, с кусками

Клиент:

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

Сервер:

  1. Принять запрос

  2. Чанк повторяется

    2А. Да:

    1. Финальный кусок:

      3А. Да - проверьте, готов ли ответ, иначе подождите (возможно, это заставит клиента повторить)

      3Б. Нет - отправить ответ "ОК"

    2B. No:

    1. Сохранить запрос куда-нибудь (список, словарь и т.д.)

    2. Это последний кусок:

      5А. Да — обработать сообщение, сохранить ответ и отправить его клиенту

      5Б. Нет - отправить сообщение "ОК"

person Varius    schedule 09.08.2012
comment
Спасибо за алгоритм, а как насчет привязки/переноса части вопроса? - person Dr.Strangelove; 10.08.2012