{"id":173,"date":"2007-03-14T16:21:42","date_gmt":"2007-03-14T23:21:42","guid":{"rendered":"http:\/\/kennyw.com\/indigo\/173"},"modified":"2007-03-14T16:21:42","modified_gmt":"2007-03-14T23:21:42","slug":"client-tcp-and-named-pipe-connection-pooling","status":"publish","type":"post","link":"https:\/\/kennyw.com\/?p=173","title":{"rendered":"Client (TCP and Named Pipe) Connection Pooling"},"content":{"rendered":"<p>Using the TCP and Named Pipe bindings give you a very clean mapping between IDuplexSessionChannel and the underlying network resource (socket or pipe). Namely, you can effectively treat a channel as 1-1 to a socket (I will use socket as shorthand for the generic &#8220;network resource&#8221; for the remainder of this post :)).<\/p>\n<p>That being said, the lifetime of the underlying socket is not necessarily 1-1 with the <a href=\"http:\/\/kennyw.com\/indigo\/140\">lifetime of the channel<\/a>. Due to our connection pooling feature in WCF, a connection can be reused over the lifetime of multiple channels. We perform connection pooling for both buffered and streaming channels.  Our connection pool is configurable through <a href=\"http:\/\/blogs.msdn.com\/drnick\/archive\/2006\/07\/06\/657619.aspx\"><code class=\"classname\">TcpConnectionPoolSettings<\/code>\/<code class=\"classname\">NamedPipeConnectionPoolSettings<\/code><\/a>. These settings include a GroupName that we use for isolation, an upper bound on our cache size (MaxOutboundConnectionsPerEndpoint), and <a href=\"http:\/\/kennyw.com\/indigo\/134\">timeout values for reliability and NLB support<\/a><\/p>\n<p>The way connection pooling works on the client is as follows:<\/p>\n<ul>\n<li>When you open a channel we will first look for a connection in our pool. This lookup is performed based on IP+port for sockets and based on endpoint Uri name for Pipes.<\/li>\n<li>If we find an available connection in our pool then we will attempt our <a href=\"http:\/\/kennyw.com\/indigo\/140\">open handshake<\/a> using .Net Framing.  If this succeeds then we will associate the connection with the new channel and return from Open. If it fails then we&#8217;ll discard the connection.  If we have not yet exceeded the binding&#8217;s OpenTimeout then we will repeat the &#8220;look in pool&#8221; process. <\/li>\n<li>If no [valid] connections are found in our pool then we will establish a new connection (again, using up to the time remaining in OpenTimeout).<\/li>\n<li>When you close a channel, after we perform our <a href=\"http:\/\/kennyw.com\/indigo\/140\">close handshake<\/a> we will consider returning the connection to our pool. If we already have reached MaxOutboundConnectionsPerEndpoint, or the connection&#8217;s lifetime has exceeded LeaseTimeout then we will close the connection instead.  The connection that is returned to the pool is the &#8220;raw&#8221; connection (the one that was initially accepted, prior to any security upgrades). In this way we can provide a transparent pool without leaking any security or other information.<\/li>\n<\/ul>\n<p>I was going to cover the server-side usage of connection pooling in this same post, but the process of accepting and reusing connections on the server is worthy of its own topic next time \ud83d\ude09<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Using the TCP and Named Pipe bindings give you a very clean mapping between IDuplexSessionChannel and the underlying network resource (socket or pipe). Namely, you can effectively treat a channel as 1-1 to a socket (I will use socket as shorthand for the generic &#8220;network resource&#8221; for the remainder of this post :)). That being [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[],"class_list":["post-173","post","type-post","status-publish","format-standard","hentry","category-indigo"],"_links":{"self":[{"href":"https:\/\/kennyw.com\/index.php?rest_route=\/wp\/v2\/posts\/173","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kennyw.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kennyw.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kennyw.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/kennyw.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=173"}],"version-history":[{"count":0,"href":"https:\/\/kennyw.com\/index.php?rest_route=\/wp\/v2\/posts\/173\/revisions"}],"wp:attachment":[{"href":"https:\/\/kennyw.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=173"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kennyw.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=173"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kennyw.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=173"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}