大きなストリームを受け入れて処理し、そのストリームを返す WCF サービス操作が必要です。
必要なものへの参照として、 Large Data Streaming に関する MSDN の記事を使用しました。私はその記事のアドバイスに従いました。
事前に質問する:
コントラクトで指定したときに、生成されたサービス操作に戻り値の型がない理由を知りたいですか?
それが予期される動作である場合、ストリームを渡して処理されたストリームを返すにはどうすればよいですか?
詳細:
入力ストリームと戻りストリームの両方に MetaData を添付する必要があるため、必要に応じてクラスを MessageContract 属性で装飾しました。
これが私の実装の簡単な概要です。
メッセージ コントラクト:
[MessageContract]
public class InputStreamMessage
{
[MessageHeader]
public InputStreamHeader Header { get; set; }
[MessageBodyMember(Order = 1)]
public Stream Data { get; set; }
}
[MessageContract]
public class OutputStreamMessage
{
[MessageHeader]
public OutputStreamHeader Header { get; set; }
[MessageBodyMember(Order = 1)]
public Stream Data { get; set; }
}
サービス契約:
[ServiceContract]
public interface IStreamService
{
[OperationContract]
OutputStreamMessage ProcessStream(InputStreamMessage input);
}
サービスの実装:
public OutputStreamMessage DoStreamOperation(InputStreamMessage input)
{
//Some logic that assigns re
OutputStreamMessage output = DoSomeNonBufferedProcessing(input);
return output;
}
クライアント側:
次に、クライアント側でサービス参照を生成し、以下のようにサービスを呼び出します。
private void PerformStreamOperation()
{
try
{
//
StreamServiceReference.StreamServiceClient client = new StreamServiceReference.StreamServiceReferenceClient();
client.Open();
//Set Header and Parameters
InputMessageHeader header = new InputMessageHeader();
//...
//... initialize header data here
//...
//... do some operation to get input stream
var inputstream = SomeOperationToGetInputStream();
//Perform Service stream action
// ____ [ Why does the generated method have the following signature, retuning void?]
// | [ If this is expected, how do I use it? ]
// |
// V
client.DoStreamOperation(header, ref inputstream);
//...
//... Do what you wish with data
//...
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString(), "Stream Processing Error");
}
}
MSDN の記事では、公式の WCF サンプルに存在するものとまったく同じコントラクトを使用しています。
Stream EchoStream(ストリームデータ)
しかし、同等の MessageContract 実装の例はありません。サンプル バージョンは期待どおりの結果をもたらします。
アップデート
- サービス参照に、予期されるメソッド シグネチャで生成された Task/Asynchronous メソッドがあることに気付きました。おそらくこれは、Stream プロパティで MessageContract を使用し、同様に構造化されたオブジェクトを返す場合、それを非同期で呼び出す必要があることを意味します。どこにも文書化されているのを見たことがありません。メソッドを使用してみます -同期操作が必要なため、機能しませんでした。
ChannelFactory
また、生成されたプロキシ クライアントの代わりに を使用してみました。EndpointAddress endpoint = new EndpointAddress("net.tcp://localhost:9910/StreamService"); channelFactory = new ChannelFactory<IStreamService>("netTcpStreamedEndPoint"); channelFactory.Endpoint.Contract.SessionMode = SessionMode.Allowed; IStreamService service = channelFactory.CreateChannel();