基于WCF会话的服务客户端跟踪

时间:2014-09-18 16:12:54

标签: wcf connection client tracker

我跟踪了Carlos Figueira关于WCF自托管服务中客户端跟踪的博客,并尝试将其客户端跟踪器用于IIS托管WCF服务。我在使用扩展类时遇到了一些问题,在创建客户端时,初始化事件永远不会为IChannelInitializer对象触发。

我们的想法是跟踪客户端与IIS中托管的基于会话的WCF服务的连接,我特别想知道客户端何时断开连接,以便我可以清理通过不同服务端点流式传输的一些数据。

在客户端上,我使用Visual Studio的解决方案资源管理器中的“添加服务引用”来生成绑定。

卡洛斯的博客: http://blogs.msdn.com/b/carlosfigueira/archive/2012/02/14/wcf-extensibility-initializers-instance-context-channel-call-context.aspx

WCF服务实现(Imlvc.cs)

[ServiceContract(SessionMode=SessionMode.Required)] 
public interface Imlvc
{
    [OperationContract]
    int MyMethod();

    [OperationContract]
    int ConnectedClients();
}

WCF服务(mlvc.svc.cs)

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class mlvc : Imlvc
{
    static int m_Counter = 0;
    public int MyMethod()
    {
        m_Counter++;
        return m_Counter;
    }
    public int ConnectedClients()
    {
        int val = ClientTrackerChannelInitializer.ConnectedClientCount;
        Debug.Write("ConnectedClients() called.");
        return val;
    }
}
public class ClientTrackerChannelInitializer : IChannelInitializer
{
    internal static int ConnectedClientCount = 0;
    public void Initialize(IClientChannel channel)
    {
        Debug.Write("Initialize was fired for ClientTrackerChannelInitializer");
        ConnectedClientCount++;
        channel.Closed += ClientDisconnected;
        channel.Faulted += ClientDisconnected;
    }
    static void ClientDisconnected(object sender, EventArgs e)
    {
        Debug.Write("ClientDisconnected() was fired for ClientTrackerChannelInitializer");
        ConnectedClientCount--;
    }
}
public class ClientTrackerEndpointBehavior : BehaviorExtensionElement, IEndpointBehavior
{
    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { }
    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) { }
    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {
        endpointDispatcher.ChannelDispatcher.ChannelInitializers.Add(new ClientTrackerChannelInitializer());
        Debug.Write("endpointDispatcher added");
    }
    public void Validate(ServiceEndpoint endpoint) { Debug.Write("endpoint Validate Fired"); }
    public override System.Type BehaviorType
    {
        get
        {
            Debug.Write("behavior property retrieved");
            return typeof(ClientTrackerEndpointBehavior);
        }
    }
    protected override object CreateBehavior()
    {
        Debug.Write("endpoint behavior created.");
        return new ClientTrackerEndpointBehavior();

    }
}

服务的Web.config

<?xml version="1.0"?>
<configuration>
<system.web>
  <customErrors mode="Off" />
  <compilation debug="false"/>
</system.web>
<system.serviceModel>
<extensions>
  <behaviorExtensions>
    <add name="myClientTracker"
          type="MasterListWCF.ClientTrackerEndpointBehavior, MasterListWCF" />
  </behaviorExtensions>
</extensions>
<services>
  <service behaviorConfiguration="sessionBehavior" name="MasterListWCF.mlvc">
    <endpoint address="" behaviorConfiguration="myClientTracker"
      binding="customBinding" bindingConfiguration="sessionHttpsBindingConfiguration"
      name="sessionHttpEndpoint" contract="MasterListWCF.Imlvc" />
    <endpoint address="mex" binding="mexHttpBinding" name="mexHttpSessionEndpoint"
      contract="IMetadataExchange" />
    <host>
      <baseAddresses>
        <add baseAddress="http://m.managedsp.com/testsvc/mlvc.svc" />
      </baseAddresses>
    </host>
  </service>
</services>
<behaviors>
  <endpointBehaviors>
    <behavior name="myClientTracker" />
  </endpointBehaviors>
  <serviceBehaviors>
    <behavior name="">
      <serviceMetadata httpGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="false" />
    </behavior>
    <behavior name="sessionBehavior">
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="true" />
      <serviceThrottling maxConcurrentCalls="500" maxConcurrentSessions="500"
        maxConcurrentInstances="500" />
    </behavior>
  </serviceBehaviors>
</behaviors>
<bindings>
  <customBinding>
    <binding name="sessionHttpsBindingConfiguration">
      <reliableSession/>
      <httpsTransport/>
    </binding>
  </customBinding>
</bindings>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
   <modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>    

创建客户端并调用服务方法的控制台应用程序

static void Main(string[] args)
{
    ImlvcClient client = new ImlvcClient();
    Console.WriteLine(client.State);
    Console.WriteLine("Connected clients " + client.ConnectedClients());
    Console.WriteLine("My method " + client.MyMethod());
    Console.WriteLine("My method " + client.MyMethod());
    Console.WriteLine("My method " + client.MyMethod());
    Console.WriteLine(client.State);
    Console.ReadKey();
}

客户端的app.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
  <extensions>
    <behaviorExtensions>
      <add name="myClientTracker"
            type="MasterListWCF.ClientTrackerEndpointBehavior, MasterListWCF" />
    </behaviorExtensions>
  </extensions>
  <client>
    <endpoint address="https://m.managedsp.com/testsvc/mlvc.svc" behaviorConfiguration="myClientTracker"
            binding="customBinding" bindingConfiguration="sessionHttpsBindingConfiguration" 
            contract="mlvc.Imlvc" name="sessionHttpEndpoint" />
  </client>
  <bindings>
    <customBinding>
      <binding name="sessionHttpsBindingConfiguration">
        <reliableSession/>
        <httpsTransport/>
      </binding>
    </customBinding>
  </bindings>
  <behaviors>
    <endpointBehaviors>
      <behavior name="myClientTracker" />
    </endpointBehaviors>
  </behaviors>
</system.serviceModel>
</configuration>

以下是控制台应用的输出

Created
Connected clients 0
My method 1
My method 2
My method 3
Opened

问题是在创建客户端时从不触发initialize事件。这是WCF进程的调试日志。您可以看到调用了ClientConnections,但从未为IChannelInitializer调用initialize方法。

'w3wp.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\testsvc\d85651f1\367baff8\assembly\dl3\edc64503\46551bf1_57d3cf01\MasterListWCF.dll', Symbols loaded.
'w3wp.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Data.Services.Design\v4.0_4.0.0.0__b77a5c561934e089\System.Data.Services.Design.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'w3wp.exe' (Managed (v4.0.30319)): Loaded 'Microsoft.GeneratedCode'
ConnectedClients() called.
The thread '<No Name>' (0x2f0) has exited with code 0 (0x0).

有人能指出我为什么没有触发Initialize方法的正确方向吗?

0 个答案:

没有答案