我试图了解如何使用 WCF 实现消息框架。目标是在 WCF 中创建一个可以通过 Tcp 处理专有格式的服务器。我不能使用 net.Tcp 绑定,因为这仅适用于 SOAP。
我需要编写一个自定义通道来接收以下格式的消息。示例消息是“5 abcde”。特别是我不确定如何在我的自定义频道中进行取景。
这是一些示例代码
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 可以从待处理的读取缓冲区“5 ab”中获取一条消息。然后第二次它可以得到剩下的信息。问题是当第一次调用 EndTryReceive 时,我被迫创建一个 Message 对象,这意味着会有部分 Message 进入通道堆栈。
我真正想做的是确保缓冲区中有完整的消息“5 abcde”,这样当我在 EndTryReceive 中构造消息时,它就是完整的消息。
有没有人有任何他们如何使用 WCF 进行自定义框架的示例?
谢谢, 瓦迪姆