возобновление файлов при загрузке на сервер с помощью wcf

Я использую WCF и пытаюсь возобновить загрузку со следующим кодом в серверном приложении:

class DataUploader : IDataUploader
{
     public void Upload(UploadMessage msg)
     {
         int speed = msg.AvgSpeed * 1024; // convert to KB
         Stream stream= msg.DataStream;
         string name = msg.VirtualPath;

         int seekPoint; // this is get reading the partial uploaded file   

         using (FileStream fs = new FileStream(@"C:\savedfile.dat, FileMode.Append))
         {
            int bufferSize = 4 * 1024; // 4KB buffer
            byte[] buffer = new byte[bufferSize];
            int bytes;

            while ((bytes = stream.Read(buffer, startPoint, bufferSize)) > 0)
            {
                fs.Write(buffer, 0, bytes);
                fs.Flush();
            }
            stream.Close();
            fs.Close();
        }
    }
}

Я пытаюсь начать читать поток с указанной точки (startPoint), потому что первые байты уже загружены. Таким образом, я мог добавить только оставшиеся байты к частично загруженному файлу. Таким образом, я получаю сообщение об ошибке с размером буфера и не могу использовать поиск, потому что метод не поддерживает исключение, поэтому я думаю, что этот подход неверен. Помощь!!

Мой сервисный контракт:

[ServiceContract]
interface IDataUploader
{
    [OperationContract]
    void Upload(UploadMessage msg);
}

Контракт моего сообщения:

[MessageContract]
public class UploadMessage
{
[MessageHeader(MustUnderstand = true)]
public string VirtualPath { get; set; }

[MessageHeader(MustUnderstand = true)]
public int AvgSpeed { get; set; }

[MessageBodyMember(Order = 1)]
public Stream DataStream { get; set; }
}

person blur    schedule 09.06.2011    source источник
comment
Какой тип креплений вы используете? Можете ли вы опубликовать интерфейсы контрактов и пример вызова клиента?   -  person Dave Ferguson    schedule 10.06.2011
comment
Используя все привязки, nettcp wshttp и basichttp, загрузка работает нормально, но я хочу возобновить загрузку, когда загрузка прекращается, потому что я использую большие файлы.   -  person blur    schedule 10.06.2011


Ответы (2)


Похоже, вы используете стандартное мыльное сообщение, а не потоковую привязку. Перейдите по этой ссылке.

Если вы не хотите использовать потоковый API-интерфейс WCF, который является собственностью WCF, я бы подумал о создании метода «фрагментирования» от клиента, если клиент загружает файл. Подобно тому, как FTP может возобновиться, я бы запросил сервер, чтобы увидеть текущее смещение, отправил блок или набор блоков, записал их в свое постоянство (память, базу данных, файл и т. д.), а затем продолжил несколько вызовов из клиент отправляет меньшие блоки (будьте осторожны с сериализацией, так как это может привести к ненужным задержкам). Этот метод должен быть тем, что вы хотите исследовать, так как это звучит так, как будто клиент «поток» на сервер.

Кстати, вы можете просмотреть следующую статью, чтобы определить, подходит ли вам использование MessageContract, а не DataContract.

http://blogs.msdn.com/b/drnick/archive/2007/07/25/data-contract-and-message-contract.aspx

person Dave Ferguson    schedule 09.06.2011
comment
Я использую потоковую передачу с nettcpbinding. Моя путаница в том, как я сказал, как добавить оставшуюся часть в файл. Не ясно. - person blur; 10.06.2011

Если вы хотите возобновить функциональность, вы не можете сделать это таким образом. Ваш клиент должен отправлять файл фрагментами и поддерживать идентификатор последнего успешно обновленного фрагмента. Служба должна обрабатывать фрагменты и добавлять их в хранилище.

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

Существует также пример реализации канала, который выполняет внутреннее разделение.

person Ladislav Mrnka    schedule 10.06.2011