2011-09-20 91 views
2

我有一個NET.TCP WCF服務器和客戶端應用程序,並希望爲每個連接的客戶端提供帶寬,TTL等服務器端組件的統計信息。WCF連接的帶寬和吞吐量

爲了得到TTL,我可以實現一種新的方法來在客戶端和服務器之間反彈並測量時間差,並測量流量,我可以簡單地計算消息中的字節數,但是我想知道是否有任何內置統計信息在ServiceHost中提供我需要的東西。

計算我的對象中的字節數也可能會引起誤解,因爲綁定將對數據應用二進制編碼。

+1

我懷疑你可以從一個自定義的MessageInspector中獲得一些數字(相當肯定我已經在這裏寫了stackoverflow),但爲了得到包括傳輸效果的精確圖片,wireshark可能會更好。 –

+0

謝謝馬克。我將實現MessageInspector添加累加字節,並從中導出字節數/秒。 – tonycoupland

回答

4

結合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 
{ 
    ... 
}