Передача больших файлов действительно является проблемой в wcf, и опция потоковой передачи ничего не решает (вам даже нужно больше памяти на сервере).
Если вы не хотите использовать сокеты, это может решить проблему с реализацией вашего собственного «протокола» для разбиения файла на блоки и передачи только отдельных блоков. Я использовал надежные сеансы и TransportWithMessageCredential.
Интерфейс сервера (или клиента) выглядит примерно так:
[ServiceContract(CallbackContract = typeof(IClient), SessionMode = SessionMode.Required)]
public interface IServer
{
[OperationContract]
FilePart GetFileChunk(string identifier, int number, int blockSize);
}
В качестве DataContract вы можете использовать что-то вроде этого:
[DataContract]
public class FilePart
{
[DataMember] public int Part;
[DataMember] public byte[] Data;
[DataMember] public int BlockSize;
}
Чтобы найти «правильный» размер блока, вам нужно немного поиграть, я рекомендую что-то около 64-512 кб. Когда они слишком малы, у вас много запросов, когда они слишком велики, они замедляются и у вас больше нагрузки на стороне сервера.
Также важно, чтобы maxReceivedMessageSize, maxBufferSize и время ожидания были достаточно высокими (в конфигурации привязки) и квоты считывателя. Для тестирования я рекомендую использовать максимум для всех полей, когда он работает, используйте значения, которые лучше подходят.
Если вы работаете с дуплексными привязками, вы можете передавать объекты с помощью ссылки. Таким образом, вы можете передавать объекты обратного вызова, чтобы вы могли лучше видеть ход передачи и так далее ...
[OperationContract IsOneWay=true]
FilePart GetFileChunk(string identifier, int number, int blockSize, ref TransferState callback);
Я думаю, что это все уловки и подсказки, которые я могу дать. Надеюсь, это поможет.