kseen
kseen

Reputation: 397

Keeping one wcf client proxy for whole app

I have highload ASP .NET MVC2 website and WCF service that site uses. Early I created one proxy every time I need it and even didn't close it. Refer to my previous question (with my big thanks for SO user Richard Blewett) I found out that I should close this proxy. In other way it will succeed sessions limit.

Now, I'm creating proxy one time app starts and then just check it and recreate it if is needed. So, here is the code:

public static bool IsProxyValid(MyServ.MyService client) {
    bool result = true;
    if ((client == null) || (client.State != System.ServiceModel.CommunicationState.Opened) // || (client.InnerChannel.State != CommunicationState.Opened)
        )            
        result = false;

    return result;
}

public static AServ.AServClient GetClient(HttpContext http) {            
    if (!IsProxyValid((MyService)http.Application["client"]))
        http.Application["client"] = new MyService();
    return (MyService)http.Application["client"];
}

public static MyServ.MyService GetClient(HttpContextBase http)
{
    if (!IsProxyValid((MyService)http.Application["client"]))
        http.Application["client"] = new MyService();
    return (MyService)http.Application["client"];
}

public ActionResult SelectDepartment(string departments)
    {
       try
        {
            MyService svc = CommonController.GetClient(this.HttpContext);                
            Department[] depsArray = svc.GetData(departments);

            // .... I cut here ....

            return View();
        }
        catch (Exception exc)
        {
            // log here                
            return ActionUnavailable();
        }
    }

So, what do you guys think about it? Should it work properly? Sometimes my app stucked. I think it is because client proxy state determines uncorrectly and app tries to use broken proxy.


POST EDIT

Also in TCP Monitor I see a lot of established connections from site to service. Why it creates a lot of connectiong insteads of using one global? Maybe some exception occured while invoking service method makes it faulted state?

Hope for your help guys!

Upvotes: 1

Views: 1293

Answers (1)

Low Flying Pelican
Low Flying Pelican

Reputation: 6054

I think you need to abort the channel if it gets faulted before creating a new one and Make sure to close/ abort old client if you creating the new client, use something like this for that (this one is used with DI in singleton)

public class MyServiceClientInitializer : IMyServiceClientInitializer
 {
        [ThreadStatic]
        private static MyServ.MyService _client;

        public MyServ.MyService Client
        {
            get
            {
                if (_client == null
                    || (_client.State != CommunicationState.Opened
                            && _client.State != CommunicationState.Opening))
                    IntializeClient();

                return _client;
            }
        }

        private void IntializeClient()
        {
            if (_client != null)
            {
                if (_client.State == CommunicationState.Faulted)
                {
                    _client.Abort();
                }
                else
                {
                    _client.Close();    
                }
            }

            string url = //get url;

            var binding = new WSHttpBinding();
            var address = new EndpointAddress(url);

            _client = new MyServ.MyService(binding, address);            
        }
}

Upvotes: 1

Related Questions