WCFを使用してメッセージフレーミングを実装する方法を理解しようとしています。目標は、Tcpを介して独自の形式を処理できるサーバーをWCFで作成することです。net.TcpバインディングはSOAP専用であるため、使用できません。
次の形式のメッセージを受信するカスタムチャネルを作成する必要があります。メッセージの例は「5abcde」です。特に、カスタムチャネルでフレーミングを行う方法がわかりません。
ここにいくつかのサンプルコードがあります
class CustomChannel: IDuplexSessionChannel
{
private class PendingRead
{
public NetworkStream Stream = null;
public byte[] Buffer = null;
public bool IsReading = false;
}
private CommunicationState state = CommunicationState.Closed;
private TcpClient tcpClient = null;
private MessageEncoder encoder = null;
private BufferManager bufferManager = null;
private TransportBindingElement bindingElement = null;
private Uri uri = null;
private PendingRead pendingRead;
public CustomChannel(Uri uri, TransportBindingElement bindingElement, MessageEncoderFactory encoderFactory, BufferManager bufferManager, TcpClient tcpClient)
{
this.uri = uri;
this.bindingElement = bindingElement;
this.tcpClient = tcpClient;
this.bufferManager = bufferManager;
state = CommunicationState.Created;
}
public IAsyncResult BeginTryReceive(TimeSpan timeout, AsyncCallback callback, object state)
{
if (this.state != CommunicationState.Opened) return null;
byte[] buffer = bufferManager.TakeBuffer(tcpClient.Available);
NetworkStream stream = tcpClient.GetStream();
pendingRead = new PendingRead { Stream = stream, Buffer = buffer, IsReading = true };
IAsyncResult result = stream.BeginRead(buffer, 0, buffer.Length, callback, state);
return result;
}
public bool EndTryReceive(IAsyncResult result, out Message message)
{
int byteCount = tcpClient.Client.EndReceive(result);
string content = Encoding.ASCII.GetString(pendingRead.buffer)
// framing logic here
Message.CreateMessage( ... )
}
}
したがって、基本的に、EndTryReceiveを初めて使用すると、保留中の読み取りバッファ「5ab」からメッセージの一部を取得できます。次に、2回目は、残りのメッセージを取得できます。問題は、EndTryReceiveが最初に呼び出されたときに、Messageオブジェクトを作成することを余儀なくされることです。これは、チャネルスタックを上る部分的なMessageがあることを意味します。
私が本当にやりたいのは、バッファに完全なメッセージ「5 abcde」があることを確認することです。これにより、EndTryReceiveでメッセージを作成すると、完全なメッセージになります。
WCFでカスタムフレーミングを行っている例はありますか?
ありがとう、Vadim