私の最終目標は、ストリーミング転送モード用に構成された WCF サービスに大きなビデオ ファイルとストリームをアップロードできるようにすることです。私が抱えている問題は、ストリームが最後まで読み取られた後にのみ、WCF クライアントがサービスに要求を発行していることです。
主な使用例は、定義済みの終了点を持たないサービスにライブ ストリームを中継することです。そのため、データを送信する前にこれらのストリームを完全に読み取ることは現実的ではありません。この機能をテストするために、「無限」ストリームを作成しました。
public class InfiniteStream : Stream
{
private Random _random;
public InfiniteStream()
{
_random = new Random(1);
}
public override int Read(byte[] buffer, int offset, int count)
{
_random.NextBytes(buffer);
Position += count;
return count;
}
// other unimportant methods
}
そして、私が見つけた例と一致して、ストリーミングアップロードを受信するための MessageContract:
[MessageContract]
public class ClipUpload : IDisposable
{
[MessageHeader(MustUnderstand = true)]
public long MediaId;
[MessageBodyMember(Order=1)]
public System.IO.Stream MediaStream;
// disposable implementaton
}
現在、私が知る限り、私のサービスはストリーミング転送用に適切に構成されており、サーバー側でストリームを問題なく読み取ることができます。対象のサーバー構成:
<basicHttpsBinding>
<binding name="A" transferMode="Streamed" maxReceivedMessageSize="4294967296" maxBufferSize="65536">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName" />
</security>
</binding>
</basicHttpsBinding>
対象のクライアント構成:
<basicHttpsBinding>
<binding name="A" transferMode="Streamed" maxBufferSize="65536">
<security mode="TransportWithMessageCredential" />
</binding>
</basicHttpsBinding>
サーバー側の操作は簡単です。私のサービスインターフェースで::
[OperationContract(IsOneWay=true)]
void UploadClip(ClipUpload upload);
実装:
public void UploadClip(ClipUpload upload)
{
using (var stream = new FileStream(@"C:\Temp\temp.mp4", FileMode.Create, FileAccess.Write))
{
upload.MediaStream.CopyTo(stream);
}
クライアントも単純な呼び出しを使用しています。
using(var stream = new InfiniteStream())
{
_service.UploadClip(1, stream);
}
繰り返しになりますが、問題は、ストリームが完全に読み取られるまでクライアントがストリーム データを送信しないことです。もちろん、これは InfiniteStream には当てはまりません。したがって、フローがサーバーの UploadClip メソッドに到達することはありません。非「無限」ストリームの場合、プロセスは機能しますが、クライアントがすべてのストリーム コンテンツをバッファリングしているように見えるため、かなりの遅延が発生します。