Есть ли способ включить сеанс и потоковую передачу в netTcpBinding? - PullRequest
5 голосов
/ 16 января 2010

Я пишу WCF-сервис, который должен передавать большие файлы, поэтому я использую потоковую передачу, но с другой стороны, мне нужно выполнить инициализацию для конкретного имени пользователя.

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

Есть ли способ включить потоковую передачу и сеанс в netTcpBinding?

Ответы [ 2 ]

4 голосов
/ 23 января 2010

Передача больших файлов действительно является проблемой в 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);   

Я думаю, что это все уловки и подсказки, которые я могу дать. Надеюсь, это поможет.

1 голос
/ 16 января 2010

Я не думаю, что WCF подходит для передачи больших файлов - попробуйте вместо этого использовать System.Net.Sockets, хотя WCF основан на них.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...