WCF连接的带宽和吞吐量

问题描述:

我有一个NET.TCP WCF服务器和客户端应用程序,并希望为每个连接的客户端提供带宽,TTL等服务器端组件的统计信息。WCF连接的带宽和吞吐量

为了得到TTL,我可以实现一种新的方法来在客户端和服务器之间反弹并测量时间差,并测量流量,我可以简单地计算消息中的字节数,但是我想知道是否有任何内置统计信息在ServiceHost中提供我需要的东西。

计算我的对象中的字节数也可能会引起误解,因为绑定将对数据应用二进制编码。

+1

我怀疑你可以从一个自定义的MessageInspector中获得一些数字(相当肯定我已经在这里写了*),但为了得到包括传输效果的精确图片,wireshark可能会更好。 –

+0

谢谢马克。我将实现MessageInspector添加累加字节,并从中导出字节数/秒。 – tonycoupland

结合this博客文章和拖网在线文档我实现了一个Message Inspector,自定义行为并将其应用于我的服务。

由于我的服务是Duplex,为了捕获所有流量,我需要将消息检查器添加到服务器端点和回调客户端运行时。这一点似乎从许多在线示例中缺失。

定制督察

public class EndPointMessageInspector : IDispatchMessageInspector, IClientMessageInspector 
{ 
    static long _bytesWritten = 0; 
    static long _bytesRead = 0; 

    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) 
    { 
     MessageBuffer buffer = request.CreateBufferedCopy(Int32.MaxValue); 
     request = buffer.CreateMessage(); 
     _bytesRead += buffer.CreateMessage().ToString().Length; 
     return null; 
    } 

    public void BeforeSendReply(ref Message reply, object correlationState) 
    { 
     if (reply != null) 
     { 
      MessageBuffer buffer = reply.CreateBufferedCopy(Int32.MaxValue); 
      reply = buffer.CreateMessage(); 
      _bytesWritten += buffer.CreateMessage().ToString().Length; 
     } 
    } 

    public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState) 
    { 
     // No replies expected from Duplex call backs 
    } 

    public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, IClientChannel channel) 
    { 
     if (request != null) 
     { 
      MessageBuffer buffer = request.CreateBufferedCopy(Int32.MaxValue); 
      request = buffer.CreateMessage(); 
      _bytesWritten += buffer.CreateMessage().ToString().Length; 
     } 
     return null; 
    } 
} 

定制服务行为

[AttributeUsage(AttributeTargets.Class)] 
public class GatherThroughputBehaviour : Attribute, IServiceBehavior, IEndpointBehavior 
{ 
    #region IServiceBehavior Members 
    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters) 
    { 
    } 

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) 
    { 
     for (int i = 0; i < serviceHostBase.ChannelDispatchers.Count; i++) 
     { 
      ChannelDispatcher channelDispatcher = serviceHostBase.ChannelDispatchers[i] as ChannelDispatcher; 
      if (channelDispatcher != null) 
      { 
       foreach (EndpointDispatcher endpointDispatcher in channelDispatcher.Endpoints) 
       { 
        EndPointMessageInspector inspector = new EndPointMessageInspector(); 
        endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector); 
       } 
      } 
     } 
    } 

    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) 
    { 
    } 
    #endregion 

    #region IEndpointBehavior Members 
    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) 
    { 
    } 

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) 
    { 
    } 

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) 
    { 
     endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new EndPointMessageInspector()); 
     endpointDispatcher.DispatchRuntime.CallbackClientRuntime.MessageInspectors.Add(new EndPointMessageInspector()); 
    } 

    public void Validate(ServiceEndpoint endpoint) 
    { 
     return; 
    } 
    #endregion 
} 

应用的行为,以我的服务

[GatherThroughputBehaviour] 
public class TunnelServer : IMyContract 
{ 
    ... 
}