﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-twzheng's cppblog-文章分类-ESFramework</title><link>http://www.cppblog.com/twzheng/category/4033.html</link><description>『站在风口浪尖紧握住鼠标旋转！』  人在台北心在汉</description><language>zh-cn</language><lastBuildDate>Mon, 15 Mar 2010 04:03:22 GMT</lastBuildDate><pubDate>Mon, 15 Mar 2010 04:03:22 GMT</pubDate><ttl>60</ttl><item><title>求windows xp 繁体版</title><link>http://www.cppblog.com/twzheng/articles/109710.html</link><dc:creator>谭文政</dc:creator><author>谭文政</author><pubDate>Sun, 14 Mar 2010 16:05:00 GMT</pubDate><guid>http://www.cppblog.com/twzheng/articles/109710.html</guid><wfw:comment>http://www.cppblog.com/twzheng/comments/109710.html</wfw:comment><comments>http://www.cppblog.com/twzheng/articles/109710.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/twzheng/comments/commentRss/109710.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/twzheng/services/trackbacks/109710.html</trackback:ping><description><![CDATA[求windows xp 繁体版，最好是台湾版的，要能一步步的手动安装(想装双系统)<br><br>找了好几天了，很多资源都下不动<br><br>今天好不容易下了一个，但是香港版的，且安装到选择盘符时，键盘所有键都不能使用，所以还是无法安装<br><br>谢谢各位大哥大姐帮帮忙，小弟感激不尽！<img src ="http://www.cppblog.com/twzheng/aggbug/109710.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/twzheng/" target="_blank">谭文政</a> 2010-03-15 00:05 <a href="http://www.cppblog.com/twzheng/articles/109710.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ESFramework介绍之（12）―― 基于Tcp连接池的消息处理器 </title><link>http://www.cppblog.com/twzheng/articles/21897.html</link><dc:creator>谭文政</dc:creator><author>谭文政</author><pubDate>Sat, 14 Apr 2007 14:38:00 GMT</pubDate><guid>http://www.cppblog.com/twzheng/articles/21897.html</guid><wfw:comment>http://www.cppblog.com/twzheng/comments/21897.html</wfw:comment><comments>http://www.cppblog.com/twzheng/articles/21897.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/twzheng/comments/commentRss/21897.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/twzheng/services/trackbacks/21897.html</trackback:ping><description><![CDATA[[源] <a href="http://zhuweisky.cnblogs.com/archive/2006/03/17/351925.html">http://zhuweisky.cnblogs.com/archive/2006/03/17/351925.html</a><br><br>前面的两篇文章我们已经介绍了Tcp连接池和Tcp连接池管理器，并且引入了ITcpPool接口，这个接口可以将单个连接池和一组连接池统一起来，使它们有相同的外部使用方式。现在我们需要考虑的问题是，当消息分派器分派一个接收到的请求时，如果这个请求需要被FS上的某个功能插件处理，那么消息分派器是如何将这个消息分派到对应的FS上去的？&nbsp;<br><br>&nbsp;&nbsp;&nbsp; 回顾介绍<a href="http://zhuweisky.cnblogs.com/archive/2006/03/14/349616.html"><font color=#1d58d1>消息分派器</font></a>时画出的各消息组件联系图，我们非常自然的想到，创建一个消息处理器，这个消息处理器将请求消息通过Tcp连接池转发给对应FS处理。这样的一个消息处理器称为&#8220;基于Tcp连接池的消息处理器&#8221;，它在消息组件联系图中的位置如下：<br><img height=396 alt="" src="http://zhuweisky.cnblogs.com/images/cnblogs_com/zhuweisky/MsgRelation2.JPG" width=417 border=0>&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;当有一个请求被分派到基于连接池的消息处理器时，它就从Tcp连接池中Rent一个NetworkStream，然后发送请求，并将接收到的回复返回给消息分派器。基于连接池的消息处理器仍然实现了IDataDealer接口，其借助ITcpPool组件来实现功能。下面给出简单伪码，因为整个实现比较复杂（错误处理、异常处理、ReRent机制等），代码比较多，所以就不列出来了，大家只要了解了主要的思想就行了，而这个思想是比较简单的。
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 10pt; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Verdana; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public</span><span style="COLOR: #000000">&nbsp;NetMessage&nbsp;DealRequestMessage(NetMessage&nbsp;reqMsg)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.Rent&nbsp;TcpStream<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2.Send&nbsp;Request<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3.Recieve&nbsp;Response<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4.Return&nbsp;Response<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000">&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></div>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">&nbsp;&nbsp;&nbsp; 最后提一句，我们在上图的AS和FS中都看到了网络组件，如果AS也采用Tcp，那么这两个组件是相同的，也就是说Tcp组件可以很方便的复用。&nbsp;<br>&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp; 在FS中，Tcp网络组件和功能插件之间是通过虚线连接起来的，也就是说网络组件并不会直接与功能插件交互，它们之间仍然存在这一个纽带，这就是消息处理器工厂，那么用于管理功能插件的工厂，就叫做&#8220;功能插件处理器工厂FunAddinDealerFactory&#8221;，这将在下文中介绍。&nbsp;</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">感谢关注！</p>
<img src ="http://www.cppblog.com/twzheng/aggbug/21897.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/twzheng/" target="_blank">谭文政</a> 2007-04-14 22:38 <a href="http://www.cppblog.com/twzheng/articles/21897.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ESFramework介绍之（11）－－ Tcp连接池管理器</title><link>http://www.cppblog.com/twzheng/articles/21896.html</link><dc:creator>谭文政</dc:creator><author>谭文政</author><pubDate>Sat, 14 Apr 2007 14:35:00 GMT</pubDate><guid>http://www.cppblog.com/twzheng/articles/21896.html</guid><wfw:comment>http://www.cppblog.com/twzheng/comments/21896.html</wfw:comment><comments>http://www.cppblog.com/twzheng/articles/21896.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/twzheng/comments/commentRss/21896.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/twzheng/services/trackbacks/21896.html</trackback:ping><description><![CDATA[<font size=2>[源] <a href="http://zhuweisky.cnblogs.com/archive/2006/03/16/351426.html">http://zhuweisky.cnblogs.com/archive/2006/03/16/351426.html</a><br><br>上文已经讲到，<span lang=EN-US>Tcp</span><span>连接池管理器为我们的应用进行了很多复杂的管理，比如功能服务器的调度（实现</span><span lang=EN-US>FS</span><span>的负载均衡）、连接池的动态添加</span><span lang=EN-US>/</span><span>移除、控制每个连接池的相关参数在</span><span lang=EN-US>UI</span><span>上的显示等，并且连接池管理器与单个连接池拥有一样的接口</span><span lang=EN-US>ITcpPool</span><span>。我们先回顾一下这个接口：</span></font><span lang=EN-US><font size=2>&nbsp;<br></font>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">interface</span><span style="COLOR: #000000">&nbsp;ITcpPool<br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RentStreamResult&nbsp;RentTcpStream(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;poolTypeKey&nbsp;,</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;serviceKey&nbsp;,</span><span style="COLOR: #0000ff">out</span><span style="COLOR: #000000">&nbsp;NetworkStream&nbsp;stream&nbsp;,</span><span style="COLOR: #0000ff">out</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;serverID)&nbsp;;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">poolTypeKey表示某个城市，serviceKey表示某项服务</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;GiveBackTcpStream(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;streamHashCode&nbsp;,</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;serverID)&nbsp;;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">将tcp连接规还给连接池</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;SetStreamDamaged(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;streamHashCode&nbsp;,</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;serverID)&nbsp;;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">poolKey如果不易保存，则此处简单的传-1即可&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">event</span><span style="COLOR: #000000">&nbsp;CallBackCountChanged&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ActiveConnectionCountChanged&nbsp;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">event</span><span style="COLOR: #000000">&nbsp;CallBackPoolStateChanged&nbsp;PoolStateChanged&nbsp;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000"></span></div>
</span>
<p><span lang=EN-US>&nbsp;&nbsp;&nbsp; RentTcpStream</span><span>方法中的</span><span lang=EN-US>serviceKey</span><span>参数反映了这样一个事实：与一个</span><span lang=EN-US>AS</span><span>相连的多个</span><span lang=EN-US>FS</span><span>中，每个</span><span lang=EN-US>FS</span><span>加载的功能插件可以是不一样的。</span></p>
<p><span><img height=229 hspace=0 src="http://zhuweisky.cnblogs.com/images/cnblogs_com/zhuweisky/Tcppool.JPG" width=372><br><br>&nbsp;&nbsp;&nbsp; 比如，上图中的</span><span lang=EN-US>3</span><span>个</span><span lang=EN-US>FS</span><span>中只有</span><span lang=EN-US>FS1</span><span>加载了前面介绍的&#8220;天气预测服务&#8221;插件，那么当一个&#8220;天气预测服务&#8221;请求到达</span><span lang=EN-US>AS</span><span>时，</span><span lang=EN-US>AS</span><span>就只能从与</span><span lang=EN-US>FS1</span><span>之间的连接池中</span><span lang=EN-US>Rent</span><span>一个</span><span lang=EN-US>Tcp</span><span>连接，而不是从</span><span lang=EN-US>FS2</span><span>或</span><span lang=EN-US>FS3</span><span>。</span><span lang=EN-US>RentTcpStream</span><span>方法的</span><span lang=EN-US>out</span><span>参数</span><span lang=EN-US>serverID</span><span>表明了这条连接是指向哪个</span><span lang=EN-US>FS</span><span>的。</span></p>
<p><span lang=EN-US><span>&nbsp;&nbsp;&nbsp; 接下来考虑这样一个问题，当一个请求到来，这个请求可以被</span><span lang=EN-US>FS1</span><span>、</span><span lang=EN-US>FS2</span><span>、</span><span lang=EN-US>FS3</span><span>处理，那么ITcpPoolsManager</span><span>到底返回哪个连接池中的连接了？答案是负载最小的那个</span><span lang=EN-US>FS</span><span>上的连接。<br></span><span lang=EN-US><span>&nbsp;&nbsp;&nbsp; 这是怎么做到的了？其实很简单。每个</span><span lang=EN-US>FS</span><span>都定时（比如一秒一次）地把自己的负载（</span><span lang=EN-US>CPU</span><span>利用率和内存利用率）通知给</span><span lang=EN-US>AS</span><span>，通知给</span><span lang=EN-US>AS</span><span>的方式可以有多种，比如</span><span lang=EN-US>.Net Remoting</span><span>。</span><span lang=EN-US>ESFramework</span><span>中有一个称为连接池调度器</span><span lang=EN-US>ITcpPoolScheduler</span><span>的东东，它记录了每个</span><span lang=EN-US>FS</span><span>实时的负载。这样当一个请求到来时，连接池管理器ITcpPoolsManager会要求连接池调度器从众多的</span><span lang=EN-US>FS</span><span>中选出一个&#8220;满足条件&#8221;且负载最小的</span><span lang=EN-US>FS</span><span>。这里的&#8220;满足条件&#8221;主要指的是对应的</span><span lang=EN-US>FS</span><span>上有能处理该请求的功能插件。实现这种调度需要的支持的各个相互协作的组件的联系图大致如下：</span><span> <br><br></span></p>
</span></span><img style="WIDTH: 615px; HEIGHT: 176px" height=158 hspace=5 src="http://zhuweisky.cnblogs.com/images/cnblogs_com/zhuweisky/Tcppool2.JPG" width=539 align=baseline><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><span>&nbsp;&nbsp;&nbsp; 图中</span><span lang=EN-US>I</span><span lang=EN-US>ServerPerfo</span><span lang=EN-US>rmanceMonitor</span><span>是用于监控本地服务器性能的组件，它可以定时发布本服务器的性能数据（主要是</span><span lang=EN-US>CPU</span><span>利用率和内存利用率），其定义如下：<br></span><span lang=EN-US>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">interface</span><span style="COLOR: #000000">&nbsp;IServerPerformanceMonitor&nbsp;<br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;Start()&nbsp;;<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;Stop()&nbsp;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;RefreshSpanSecs{</span><span style="COLOR: #0000ff">get</span><span style="COLOR: #000000">&nbsp;;</span><span style="COLOR: #0000ff">set</span><span style="COLOR: #000000">&nbsp;;}<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">event</span><span style="COLOR: #000000">&nbsp;CBackServerPerformance&nbsp;ServerPerformanceDataRefreshed&nbsp;;<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="COLOR: #000000">&nbsp;<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">delegate</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;CBackServerPerformance(ServerPerformance&nbsp;performance)&nbsp;;<br>&nbsp;<br></span><span style="COLOR: #008080">13</span>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;ServerPerformance<br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000">&nbsp;&nbsp;CpuUsagePercent&nbsp;;<br></span><span style="COLOR: #008080">16</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000">&nbsp;&nbsp;MemoryUsagePercent&nbsp;;<br></span><span style="COLOR: #008080">17</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;</span></div>
&nbsp;</span>
<p><span>连接池调度器</span><span lang=EN-US>ITcpPoolScheduler</span><span>的定义如下：<br></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">interface</span><span style="COLOR: #000000">&nbsp;ITcpPoolScheduler<br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">以下方法属性仅仅由多连接池管理者调用</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;GetNextTcpPool(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;poolTypeKey)&nbsp;;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">返回的是某连接池的服务端点的serverID&nbsp;，如果没有可用的返回-1</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;GetNextTcpPool(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;poolTypeKey&nbsp;,</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;serviceKey)&nbsp;;&nbsp;<br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;Initialize()&nbsp;;<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;Dispose()&nbsp;;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">还原到未初始化的状态</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;SetServerState(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;serverID&nbsp;,</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;activated)&nbsp;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;AddServer(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;serverID)&nbsp;;<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;RemoveServer(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;serverID)&nbsp;;<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">以下方法属性由外部指定或调用</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;SetPerformance(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;serverID&nbsp;,</span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000">&nbsp;cpuUsage&nbsp;,</span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000">&nbsp;memUsage)&nbsp;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">16</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ITcpPoolHelper&nbsp;&nbsp;&nbsp;&nbsp;TcpPoolHelper{</span><span style="COLOR: #0000ff">set</span><span style="COLOR: #000000">&nbsp;;}<br></span><span style="COLOR: #008080">17</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}</span></div>
<p></span><span>&nbsp;&nbsp;&nbsp; 为了使负载均衡的效果更好，</span><span lang=EN-US>ITcpPoolScheduler</span><span>可以实现的非常复杂，比如进行历史记录统计、分析、预测等。</span><span lang=EN-US>ESFramework</span><span>给出了默认实现</span><span lang=EN-US>TcpPoolScheduler</span><span>。</span></p>
<p><span lang=EN-US>&nbsp;&nbsp;&nbsp; 在组件联系图中还有一个IPoolEndPointsDisplayer</span><span>组件，它用于在</span><span lang=EN-US>UI</span><span>上显示每个功能服务器的详细信息和性能数据。<br></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080">1</span>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">interface</span><span style="COLOR: #000000">&nbsp;IPoolEndPointsDisplayer<br></span><span style="COLOR: #008080">2</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">3</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;RegisterFs(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;serverID&nbsp;,</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">&nbsp;serverName&nbsp;,IPEndPoint&nbsp;ipe&nbsp;,</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;exceptCount)&nbsp;;<br></span><span style="COLOR: #008080">4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;UnRegisterFs(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;serverID)&nbsp;;<br></span><span style="COLOR: #008080">5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;SetFsState(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;serverID&nbsp;,</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;activated)&nbsp;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">6</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;SetActiveCount(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;serverID&nbsp;,</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;activeCount)&nbsp;;<br></span><span style="COLOR: #008080">7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;UpdateFsPerformance(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;serverID&nbsp;,</span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000">&nbsp;cpuUsage&nbsp;,</span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000">&nbsp;memUsage)&nbsp;;<br></span><span style="COLOR: #008080">8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;Clear()&nbsp;;<br></span><span style="COLOR: #008080">9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}</span></div>
<p></span><span>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp; </span><span lang=EN-US>FS</span><span>管理器管理连接上本</span><span lang=EN-US>AS</span><span>的每个功能服务器，这将在后文中讲到。<br></span><span>&nbsp;&nbsp;&nbsp; 除了</span><span lang=EN-US>ITcpPool</span><span>接口，连接池管理器还实现了</span><span lang=EN-US>ITcpPoolsManager</span><span>接口：</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">interface</span><span style="COLOR: #000000">&nbsp;ITcpPoolsManager&nbsp;:ITcpPool<br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TcpPoolSchedulerTypeString{</span><span style="COLOR: #0000ff">set</span><span style="COLOR: #000000">&nbsp;;}&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">"ESFramework.Network.TcpPool.TcpPoolScheduler&nbsp;,ESFramework"</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ArrayList&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PoolEndPointList{</span><span style="COLOR: #0000ff">set</span><span style="COLOR: #000000">&nbsp;;}&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">连接池的服务端PoolEndPointInfo列表&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ReconnectSpan{</span><span style="COLOR: #0000ff">get</span><span style="COLOR: #000000">&nbsp;;</span><span style="COLOR: #0000ff">set</span><span style="COLOR: #000000">&nbsp;;}&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;分钟&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Initialize()&nbsp;;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">初次建立连接池</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dispose()&nbsp;;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">还原到没有初始化的状态</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AddPool(PoolEndPointInfo&nbsp;info)&nbsp;;<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RemovePool(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;serverID)&nbsp;;<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DisposePoolConnections(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;serverID)&nbsp;;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">编号为serverID的服务器已停止，所以释放对应的Pool，但是不删除池，仍然定时重连</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ReconnectPool(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;serverID)&nbsp;;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">曾停止的服务器已启动完毕，所以可以重连了</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #808080">///</span><span style="COLOR: #008000">&nbsp;</span><span style="COLOR: #808080">&lt;summary&gt;</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">16</span>&nbsp;<span style="COLOR: #008000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #808080">///</span><span style="COLOR: #008000">&nbsp;可直接使用&nbsp;ESFramework.Network.TcpPool.PoolEndPointsDisplayer<br></span><span style="COLOR: #008080">17</span>&nbsp;<span style="COLOR: #008000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #808080">///</span><span style="COLOR: #008000">&nbsp;</span><span style="COLOR: #808080">&lt;/summary&gt;</span><span style="COLOR: #808080"><br></span><span style="COLOR: #008080">18</span>&nbsp;<span style="COLOR: #808080"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IPoolEndPointsDisplayer&nbsp;PoolEndPointsDisplayer{</span><span style="COLOR: #0000ff">set</span><span style="COLOR: #000000">&nbsp;;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">19</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">20</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">由ITcpPoolScheduler使用</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">21</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;SetPerformance(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;serverID&nbsp;,</span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000">&nbsp;cpuUsage&nbsp;,</span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000">&nbsp;memUsage)&nbsp;;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">22</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ITcpPoolHelper&nbsp;&nbsp;&nbsp;&nbsp;TcpPoolHelper{</span><span style="COLOR: #0000ff">set</span><span style="COLOR: #000000">&nbsp;;}&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">可由ESFramework.Architecture.LBS.FourTier.FsManager提供</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">23</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;</span></div>
<p></span><span lang=EN-US>&nbsp;&nbsp;&nbsp; AddPool</span><span>方法和</span><span lang=EN-US>RemovePool</span><span>方法表明可以动态的添加</span><span lang=EN-US>/</span><span>移除</span><span lang=EN-US>Tcp</span><span>连接池。注意接口中的</span><span lang=EN-US>SetPerformance</span><span>方法，这个方法将被</span><span lang=EN-US>FS</span><span>管理器调用，用于把从</span><span lang=EN-US>Remoting</span><span>接收到的</span><span lang=EN-US>FS</span><span>的性能数据通知给</span><span lang=EN-US>ITcpPoolsManager</span><span>，然后</span><span lang=EN-US>ITcpPoolsManager</span><span>再把这些数据提交给</span><span lang=EN-US>ITcpPoolScheduler</span><span>记录，当需要进行调度的时候，</span><span lang=EN-US>ITcpPoolScheduler</span><span>从这些记录中进行分析计算并找到负载最小的</span><span lang=EN-US>FS</span><span>。</span><span lang=EN-US>TcpPoolSchedulerTypeString</span><span>属性用于向连接池管理器提供调度者的实际类型，管理器将会通过反射创建调度者的实例。</span></p>
<p><span>还有一个需要设置的属性</span><span lang=EN-US>ITcpPoolHelper</span><span>：<br></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080">1</span>&nbsp;<span style="COLOR: #0000ff">&nbsp;&nbsp;&nbsp; public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">interface</span><span style="COLOR: #000000">&nbsp;ITcpPoolHelper<br></span><span style="COLOR: #008080">2</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">3</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;ContainsService(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;serverID&nbsp;,</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;serviceKey)&nbsp;;<br></span><span style="COLOR: #008080">4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;ServerIsTheType(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;serverID&nbsp;,</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;destType)&nbsp;;<br></span><span style="COLOR: #008080">5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;ServerIsCompatible(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;serverID&nbsp;,</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;destType&nbsp;,</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;serviceKey)&nbsp;;<br></span><span style="COLOR: #008080">6</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">&nbsp;GetServerNameByID(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;serverID)&nbsp;;<br></span><span style="COLOR: #008080">7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}</span></div>
<p></span><span>&nbsp;&nbsp;&nbsp; 由于这个接口提供了每个功能服务器详细信息，所以这个接口的实现可以直接由前面提到的</span><span lang=EN-US>FS</span><span>管理器顺带实现。</span><span lang=EN-US><br><br>&nbsp;&nbsp;&nbsp; ITcpPoolsManager</span><span>是一个比较复杂的组件，它需要涉及到多个组件的协作。所以如果看完这篇文章，仍然还有些不清楚的地方，是很正常的。在后面系列文章的继续讲述中，这些不清晰的地方会慢慢拨开迷雾。<br><br>感谢关注。<br></span></p>
<img src ="http://www.cppblog.com/twzheng/aggbug/21896.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/twzheng/" target="_blank">谭文政</a> 2007-04-14 22:35 <a href="http://www.cppblog.com/twzheng/articles/21896.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ESFramework介绍之（10）－－ Tcp连接池</title><link>http://www.cppblog.com/twzheng/articles/21895.html</link><dc:creator>谭文政</dc:creator><author>谭文政</author><pubDate>Sat, 14 Apr 2007 14:17:00 GMT</pubDate><guid>http://www.cppblog.com/twzheng/articles/21895.html</guid><wfw:comment>http://www.cppblog.com/twzheng/comments/21895.html</wfw:comment><comments>http://www.cppblog.com/twzheng/articles/21895.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/twzheng/comments/commentRss/21895.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/twzheng/services/trackbacks/21895.html</trackback:ping><description><![CDATA[[源] <a href="http://zhuweisky.cnblogs.com/archive/2006/03/16/351301.html">http://zhuweisky.cnblogs.com/archive/2006/03/16/351301.html</a><br><br>凡是带有&#8220;池&#8221;的，比如数据库连接池、对象池、缓冲区池（后面可以看到<span lang=EN-US>IBuffPool</span><span>）等等，都是为了避免资源的反复创建</span><span lang=EN-US>/</span><span>销毁所带来的开销。需要为哪些资源对象建立&#8220;池&#8221;了？这些资源对象通常符合下面几个特性：<br></span><span lang=EN-US><span>（1）</span><span>在应用中需要反复的被创建</span><span lang=EN-US>/</span><span>销毁。<br></span><span lang=EN-US><span>（2）</span><span>创建</span><span lang=EN-US>/</span><span>销毁的开销比较大<br></span><span lang=EN-US><span>（3）</span><span>应用中给定时刻，对该资源对象的数量要求比较大<br></span><span lang=EN-US><span>（4）</span><span>资源对象最好是无状态的（</span><span lang=EN-US>Stateless</span><span>），这样方便直接复用<br></span><span lang=EN-US><span><br>&nbsp;&nbsp;&nbsp;&nbsp;</span>AS（<a href="http://zhuweisky.cnblogs.com/archive/2006/03/15/350408.html"><font color=#1d58d1>回顾</font></a>）</span><span>将所有的功能服务请求转发给为该</span><span lang=EN-US>AS</span><span>提供服务的</span><span lang=EN-US>FS</span><span>群中的一个（参见。。。），然后</span><span lang=EN-US>FS</span><span>将请求交给对应的功能插件处理。那么</span><span lang=EN-US>AS</span><span>和</span><span lang=EN-US>FS</span><span>之间的通信通过什么方式进行了？可选的方式有</span><span lang=EN-US>.netRemoting</span><span>、</span><span lang=EN-US>WebService</span><span>、</span><span lang=EN-US>Tcp/Udp</span><span>等。基于效率和准确性的考虑，</span><span lang=EN-US>WebService</span><span>和</span><span lang=EN-US>Udp</span><span>是不大合适的。那么</span><span lang=EN-US>TCP</span><span>和</span><span lang=EN-US>.netRemoting</span><span>，到底选用哪个？我们知道</span><span lang=EN-US>.netRemoting</span><span>底层也是基于</span><span lang=EN-US>Tcp</span><span>或</span><span lang=EN-US>Http</span><span>协议的，为了做到模拟本地方法调用的方式，</span><span lang=EN-US>.NETRemoting</span><span>也做了很多转换的操作（堆栈帧《＝》消息），导致了一些开销，而直接使用</span><span lang=EN-US>Tcp</span><span>则可以避免，而且</span><span lang=EN-US>AS</span><span>和</span><span lang=EN-US>FS</span><span>之间的消息的格式是兼容的（主要是使用了完全相同的消息头，这就够了），也就是说一条消息从客户端发出，可以不需做任何转换就直接被</span><span lang=EN-US>FS</span><span>的功能插件处理（加密、压缩不计在内）。<br></span><span lang=EN-US><span><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>如你所想，</span><span lang=EN-US>ESFramework</span><span>推荐的方式是</span><span lang=EN-US>AS</span><span>和</span><span lang=EN-US>FS</span><span>直接通过低层的</span><span lang=EN-US>Tcp</span><span>进行通信。为了避免</span><span lang=EN-US>Tcp</span><span>连接不断建立、销毁所带来的开销，</span><span lang=EN-US>AS</span><span>和</span><span lang=EN-US>FS</span><span>通信前，可以建立</span><span lang=EN-US>Tcp</span><span>连接池。本文就关注</span><span lang=EN-US>Tcp</span><span>连接池的原理和实现。<br></span><span lang=EN-US><span><br>&nbsp;&nbsp;&nbsp; </span>Tcp</span><span>连接池中存放的是</span><span lang=EN-US>Tcp</span><span>连接――即</span><span lang=EN-US>NetworkStream</span><span>对象，当应用需要使用时，就从</span><span lang=EN-US>Tcp</span><span>连接池中租借&#8220;</span><span lang=EN-US>Rent</span><span>&#8221;一条连接，用完后再归还&#8220;</span><span lang=EN-US>GiveBack</span><span>&#8221;给连接池。
<div><span>public</span><span>&nbsp;</span><span>class</span><span>&nbsp;TcpStreamPool&nbsp;:ITcpStreamPool&nbsp;,ITcpPool</span></div>
<p></span><span lang=EN-US><span>&nbsp;&nbsp;&nbsp;&nbsp;从上面的定义</span><span>可以看到</span><span lang=EN-US>TcpStreamPool</span><span>从两个接口继承：</span><span lang=EN-US>ITcpPool</span><span>和</span><span lang=EN-US>ITcpStreamPool</span><span>。先看看</span><span lang=EN-US>ITcpStreamPool</span><span>的定义：</p>
<div><span>&nbsp;1</span>&nbsp;&nbsp;&nbsp;&nbsp; <span>///</span><span>&nbsp;</span><span>&lt;summary&gt;</span><span><br></span><span>&nbsp;2</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>///</span><span>&nbsp;ITCPStreamPool&nbsp;tcp连接池用于管理大量的TCP连接<br></span><span>&nbsp;3</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>///</span><span>&nbsp;&nbsp;作者：朱伟&nbsp;sky.zhuwei@163.com&nbsp;&nbsp;<br></span><span>&nbsp;4</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>///</span><span>&nbsp;sky&nbsp;2005.02.24<br></span><span>&nbsp;5</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>///</span><span>&nbsp;</span><span>&lt;/summary&gt;</span><span><br></span><span>&nbsp;6</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>public</span><span>&nbsp;</span><span>interface</span><span>&nbsp;ITcpStreamPool&nbsp;<br></span><span>&nbsp;7</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span>&nbsp;8</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>int</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ServerID&nbsp;{</span><span>get</span><span>&nbsp;;</span><span>set</span><span>&nbsp;;}<br></span><span>&nbsp;9</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>int</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;StreamCount&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</span><span>get</span><span>&nbsp;;</span><span>set</span><span>&nbsp;;}&nbsp;</span><span>//</span><span>期望连接总数</span><span><br></span><span>10</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>int</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ActiveConnectionCount&nbsp;{</span><span>get</span><span>&nbsp;;}&nbsp;</span><span>//</span><span>实际可用的连接数&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span><br></span><span>11</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IPEndPoint&nbsp;&nbsp;FsIpe&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</span><span>get</span><span>&nbsp;;</span><span>set</span><span>&nbsp;;}&nbsp;</span><span>//</span><span>功能服务器的IPE</span><span><br></span><span>12</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>int</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ReconnectSpan{</span><span>get</span><span>&nbsp;;</span><span>set</span><span>&nbsp;;}&nbsp;</span><span>//</span><span>&nbsp;分钟&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span><br></span><span>13</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>bool</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IsActive{</span><span>get</span><span>;}<br></span><span>14</span>&nbsp;<span><br></span><span>15</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>void</span><span>&nbsp;ReConnect()&nbsp;;&nbsp;</span><span>//</span><span>手动重连</span><span><br></span><span>16</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>void</span><span>&nbsp;Initialize()&nbsp;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span>17</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>void</span><span>&nbsp;DisposeConnections()&nbsp;;&nbsp;</span><span>//</span><span>释放池中所有连接，可以通过ReConnect来重新建立连接&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span><br></span><span>18</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>void</span><span>&nbsp;SetStreamDamaged(</span><span>int</span><span>&nbsp;streamHashCode)&nbsp;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span>19</span>&nbsp;<span><br></span><span>20</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NetworkStream&nbsp;RentTcpStream()&nbsp;;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span>21</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>void</span><span>&nbsp;GiveBackTcpStream(</span><span>int</span><span>&nbsp;streamHashCode)&nbsp;;</span><span>//</span><span>将tcp连接规还给连接池</span><span><br></span><span>22</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;</span></div>
<p></span><span lang=EN-US>&nbsp;&nbsp;&nbsp; AS</span><span>和每个</span><span lang=EN-US>FS</span><span>之间都有一个连接池，每个功能服务器的区分是通过</span><span lang=EN-US>ServerID</span><span>来的，所以连接池也有一个</span><span lang=EN-US>ServerID</span><span>属性标志了本连接池是与哪个</span><span lang=EN-US>FS</span><span>相连的。</span><span lang=EN-US>ReconnectSpan</span><span>属性表明连接池要支持重连机制，即当连接池中的所有连接都断开后（可能是</span><span lang=EN-US>FS</span><span>掉线引起的），连接池应能定时重连</span><span lang=EN-US>FS</span><span>，直至该池中的所有连接重新建立。<br></span><span lang=EN-US><span>&nbsp;&nbsp;&nbsp; 如果应用从连接池</span><span lang=EN-US>Rent</span><span>了一条连接，然后在使用的过程中该连接断开了，则应用应该调用连接池的</span><span lang=EN-US>SetStreamDamaged</span><span>方法通知连接池该连接已不可用。</span><span lang=EN-US>RentTcpStream</span><span>方法和</span><span lang=EN-US>GiveBackTcpStream</span><span>方法是我们最常用的租借</span><span lang=EN-US>/</span><span>归还连接的方法了。<br></span><span lang=EN-US><span>&nbsp; &nbsp; </span><span>注意，很多方法的参数中有</span><span lang=EN-US>streamHashCode</span><span>参数，它是</span><span lang=EN-US>NetworkStream</span><span>对象的</span><span lang=EN-US>Hashcode</span><span>，系统中的每个</span><span lang=EN-US>NetworkStream</span><span>对象的</span><span lang=EN-US>HashCode</span><span>是不同的，并且，它的</span><span lang=EN-US>HashCode</span><span>在</span><span lang=EN-US>NetworkStream</span><span>对象的整个生命期间不变，所以可以使用</span><span lang=EN-US>HashCode</span><span>唯一标志每个连接。</span></p>
<p><span lang=EN-US><span>&nbsp;&nbsp; &nbsp;</span><span>似乎，</span><span lang=EN-US>ITcpStreamPool</span><span>接口已经反映了一个连接池的所有东西，是的。那么</span><span lang=EN-US>ITcpPool</span><span>接口又起什么作用了？现看看</span><span lang=EN-US>ITcpPool</span><span>的样子：<br></p>
<div><span>&nbsp;1</span>&nbsp;<span>///</span><span>&nbsp;</span><span>&lt;summary&gt;</span><span><br></span><span>&nbsp;2</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>///</span><span>&nbsp;ITcpPool&nbsp;用于将一个TCP连接池和一组TCP连接池统一起来。这样消息分派器只需使用ITcpPool接口即可。<br></span><span>&nbsp;3</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>///</span><span>&nbsp;zhuweisky&nbsp;<br></span><span>&nbsp;4</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>///</span><span>&nbsp;</span><span>&lt;/summary&gt;</span><span><br></span><span>&nbsp;5</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>public</span><span>&nbsp;</span><span>interface</span><span>&nbsp;ITcpPool<br></span><span>&nbsp;6</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span>&nbsp;7</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RentStreamResult&nbsp;RentTcpStream(</span><span>int</span><span>&nbsp;poolTypeKey&nbsp;,</span><span>int</span><span>&nbsp;serviceKey&nbsp;,</span><span>out</span><span>&nbsp;NetworkStream&nbsp;stream&nbsp;,</span><span>out</span><span>&nbsp;</span><span>int</span><span>&nbsp;serverID)&nbsp;;</span><span>//</span><span>poolTypeKey表示某个城市，serviceKey表示某项服务</span><span><br></span><span>&nbsp;8</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>void</span><span>&nbsp;GiveBackTcpStream(</span><span>int</span><span>&nbsp;streamHashCode&nbsp;,</span><span>int</span><span>&nbsp;serverID)&nbsp;;</span><span>//</span><span>将tcp连接规还给连接池</span><span><br></span><span>&nbsp;9</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>void</span><span>&nbsp;SetStreamDamaged(</span><span>int</span><span>&nbsp;streamHashCode&nbsp;,</span><span>int</span><span>&nbsp;serverID)&nbsp;;</span><span>//</span><span>poolKey如果不易保存，则此处简单的传-1即可&nbsp;&nbsp;&nbsp;&nbsp;</span><span><br></span><span>10</span>&nbsp;<span><br></span><span>11</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>event</span><span>&nbsp;CallBackCountChanged&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ActiveConnectionCountChanged&nbsp;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span>12</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>event</span><span>&nbsp;CallBackPoolStateChanged&nbsp;PoolStateChanged&nbsp;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span>13</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span>14</span>&nbsp;<span><br></span><span>15</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>public</span><span>&nbsp;</span><span>delegate</span><span>&nbsp;</span><span>void</span><span>&nbsp;CallBackCountChanged(</span><span>int</span><span>&nbsp;serverID&nbsp;,</span><span>int</span><span>&nbsp;activeConnCount)&nbsp;;<br></span><span>16</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>public</span><span>&nbsp;</span><span>delegate</span><span>&nbsp;</span><span>void</span><span>&nbsp;CallBackPoolStateChanged(</span><span>int</span><span>&nbsp;serverID&nbsp;,</span><span>bool</span><span>&nbsp;disconnected)&nbsp;;<br></span><span>17</span>&nbsp;<span><br></span><span>18</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>public</span><span>&nbsp;</span><span>enum</span><span>&nbsp;RentStreamResult<br></span><span>19</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span>20</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Succeed&nbsp;,Busy&nbsp;,TheServiceNotExist<br></span><span>21</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;}</span></div>
<p></span><span lang=EN-US><span>&nbsp;&nbsp;&nbsp; 你可能已经发现，</span><span lang=EN-US>ITcpPool</span><span>中的所有元素在</span><span lang=EN-US>ITcpStreamPool</span><span>接口中都可以找到对应物，只是有些方法的参数变复杂了。这主要是因为<span lang=EN-US>ITcpStreamPool</span><span>接口针对的是一个FS，而<span lang=EN-US>ITcpPool可能是针对一个FS也可能是一组FS。当<span lang=EN-US>ITcpPool背后是一组FS时，就</span>需要参数ServerID来区分每一个FS。</span><span>我们知道，</span><span lang=EN-US>AS</span><span>和对应的每个</span><span lang=EN-US>FS</span><span>之间都使用一个</span><span lang=EN-US>Tcp</span><span>连接池通信：<br><img height=229 hspace=5 src="http://zhuweisky.cnblogs.com/images/cnblogs_com/zhuweisky/Tcppool.JPG" width=372 align=baseline></span></span></span>&nbsp;</p>
<p><span lang=EN-US><span>&nbsp;&nbsp;&nbsp; </span><span>所有的这些连接池需要被管理起来，</span><span lang=EN-US>ESFramework</span><span>中的</span><span lang=EN-US>ITcpPoolsManager</span><span>（</span><span>连接池管理器）组件实现了对多个</span><span lang=EN-US>Tcp</span><span>连接池的管理。为了把连接池管理器和单个连接池统一起来，使它们有相同的外部接口，所以引入了</span><span lang=EN-US>ITcpPool</span><span>接口。<br>&nbsp;&nbsp;&nbsp; 这样做的好处是，在应用中直接使用</span><span lang=EN-US>ITcpPool</span><span>接口就可以了，而不用关心这个接口背后是一个&#8220;单个连接池&#8221;（对应单个</span><span lang=EN-US>FS</span><span>）还是由连接池管理器管理的&#8220;一组连接池&#8221;（对应多个</span><span lang=EN-US>FS</span><span>）。而且</span><span lang=EN-US>ITcpPoolsManager</span><span>为我们的应用进行了很多复杂的管理，比如动能服务器的调度（实现</span><span lang=EN-US>FS</span><span>的负载均衡）、连接池的动态添加</span><span lang=EN-US>/</span><span>移除等。这些将在下文中介绍。<br><br>感谢关注。<br></span></p>
</span></span></span></span></span></span></span></span></span></span></span>
<img src ="http://www.cppblog.com/twzheng/aggbug/21895.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/twzheng/" target="_blank">谭文政</a> 2007-04-14 22:17 <a href="http://www.cppblog.com/twzheng/articles/21895.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>