Как использовать потоковый SQL-файл Win32 API и поддерживать потоковую передачу WCF - PullRequest
3 голосов
/ 21 мая 2010

Я использую тип потока файлов сервера Sql для хранения больших файлов в серверной части. Я пытаюсь использовать WCf для потоковой передачи файла клиентам.

Я могу получить дескриптор файла с помощью SQLFileStream (API). Затем я пытаюсь вернуть этот поток. Я реализовал порцию данных на стороне клиента, чтобы извлечь данные из потока.

Я могу сделать это для обычного файлового потока и потока памяти. Кроме того, если я конвертировать, то sqlfilestream в памяти, которая также работает. Единственная мысль, которая не работает, это когда я пытаюсь вернуть sqlfilestream. Что я делаю не так.

Я пробовал как nettcpbinding с включенной потоковой передачей, так и http-привязку с кодировкой MTOM.

Это сообщение об ошибке:


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

Вот мой пример кода

        RemoteFileInfo info = new RemoteFileInfo();
        info.FileName = "SampleXMLFileService.xml";

        string pathName = DataAccess.GetDataSnapshotPath("DataSnapshot1");

        SqlConnection connection = DataAccess.GetConnection();            

        SqlTransaction sqlTransaction = connection.BeginTransaction("SQLSileStreamingTrans");
        SqlCommand command = new SqlCommand();
        command.Connection = connection;
        command.Transaction = sqlTransaction;
        command.CommandText = "SELECT GET_FILESTREAM_TRANSACTION_CONTEXT()";

        byte[] transcationContext = command.ExecuteScalar() as byte[];

        SqlFileStream stream = new SqlFileStream(pathName, transcationContext, FileAccess.Read);

// byte [] bytes = new byte [stream.Length]; // stream.Read (bytes, 0, (int) stream.Length);

// Stream reeturnStream = stream; // MemoryStream memoryStream = new MemoryStream (bytes);

        info.FileByteStream = stream;

        info.Length = info.FileByteStream.Length;

        connection.Close();

        return info;

    [MessageContract]
    public class RemoteFileInfo : IDisposable
    {
        [MessageHeader(MustUnderstand = true)]
        public string FileName;

        [MessageHeader(MustUnderstand = true)]
        public long Length;

        [MessageBodyMember(Order = 1)]
        public System.IO.Stream FileByteStream;

        public void Dispose()
        {
            if (FileByteStream != null)
            {
                FileByteStream.Close();
                FileByteStream = null;
            }
        }
    }

Любая помощь приветствуется

1 Ответ

2 голосов
/ 22 июня 2010

Я только что решил это для моей ситуации.

Для моей службы WCF установлено значение InstanceContextMode.PerCall.

Когда я запрашиваю поток, я должен оставить транзакцию / соединение открытым, пока объект не будет использован клиентом. Это делается с помощью метода Dispose службы (если вы реализуете IDisposable, WCF автоматически вызовет для вас Dispose).

Работает для меня как прелесть, поток читается на клиенте без проблем.

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