возобновление файлов при загрузке на сервер с помощью wcf - PullRequest
0 голосов
/ 10 июня 2011

Я использую 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; }
}

Ответы [ 2 ]

0 голосов
/ 10 июня 2011

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

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

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

0 голосов
/ 10 июня 2011

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

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

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

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

...