100165471.htm

来自「C#高级编程(第三版),顶死你们。。 。up」· HTM 代码 · 共 150 行 · 第 1/2 页

HTM
150
字号
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // register the channel</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 60.3pt"><span lang="EN-US">ChannelServices.RegisterChannel(tcpChannel);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 60.3pt"><span lang="EN-US">ChannelServices.RegisterChannel(httpChannel);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //...</span></p>
<p class="2" style="MARGIN-TOP: 0cm; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p class="MsoNormal"><span style="COLOR: black; FONT-FAMILY: 宋体">信道类必须实现</span><span lang="EN-US" style="COLOR: black">IChannel</span><span style="COLOR: black; FONT-FAMILY: 宋体">接口。</span><span lang="EN-US" style="COLOR: black">IChannel</span><span style="COLOR: black; FONT-FAMILY: 宋体">接口有以下两个属性:</span></p>
<p class="1" style="MARGIN-LEFT: 37.55pt; FTEL: -16.1pt"><span lang="EN-US">●<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span lang="EN-US">ChannelName</span><span style="FONT-FAMILY: 宋体">:这个属性是只读的,它返回信道的名称。信道的名称取决于协议的类型,<span style="LETTER-SPACING: 0.1pt">例如,</span></span><span lang="EN-US">HTTP</span><span style="FONT-FAMILY: 宋体">信道的名称为</span><span lang="EN-US">HTTP</span><span style="FONT-FAMILY: 宋体">。</span></p>
<p class="1" style="MARGIN-LEFT: 37.55pt; FTEL: -16.1pt"><span lang="EN-US">●<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span lang="EN-US">ChannelPriority</span><span style="FONT-FAMILY: 宋体">:这个属性也是只读的。在客户机和服务器之间可以使用多个信道进行<span style="LETTER-SPACING: 0.1pt">通</span>信,优先权定义了信道的次序。在客户机上,具有较高优先权的信道先与服务器进行连接。优先值越大,优先权就越大,其默认值是</span><span lang="EN-US">1</span><span style="FONT-FAMILY: 宋体">,但允许使用负值创建较低的优</span><span lang="EN-US">&nbsp;&nbsp;&nbsp; </span><span style="FONT-FAMILY: 宋体">先权。</span></p>
<p class="MsoNormal"><span style="COLOR: black; FONT-FAMILY: 宋体">实现的其他接口要根据信道的类型而决定,服务器信道实现的接口是</span><span lang="EN-US" style="COLOR: black">IChannelReceiver</span><span style="COLOR: black; FONT-FAMILY: 宋体">,而客户信道实现的接口是</span><span lang="EN-US" style="COLOR: black">IChannelSender</span><span style="COLOR: black; FONT-FAMILY: 宋体">。</span></p>
<p class="MsoNormal"><span lang="EN-US">HTTPChannel</span><span style="FONT-FAMILY: 宋体">类和</span><span lang="EN-US">TcpChannel</span><span style="FONT-FAMILY: 宋体">类都可以用在服务器和客户机。它们实现</span><span lang="EN-US">IChannelSender</span><span style="FONT-FAMILY: 宋体">接口和</span><span lang="EN-US"> IChannelReceiver</span><span style="FONT-FAMILY: 宋体">接口。这些接口都是由</span><span lang="EN-US">IChannel</span><span style="FONT-FAMILY: 宋体">接口派生而来的。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">客户端的</span><span lang="EN-US">IChannelSender</span><span style="FONT-FAMILY: 宋体">除了有</span><span lang="EN-US">IChannel</span><span style="FONT-FAMILY: 宋体">之外,还有一个方法</span><span lang="EN-US">CreateMessageSink()</span><span style="FONT-FAMILY: 宋体">,这个方法返回一个实现</span><span lang="EN-US">IMessageSink</span><span style="FONT-FAMILY: 宋体">接口的对象。</span><span lang="EN-US">IMessageSink</span><span style="FONT-FAMILY: 宋体">接口除了可以把异步消息放到信道中之外,还可以把同步消息放到信道中。在使用服务器端的接口</span><span lang="EN-US">IChannelReceiver</span><span style="FONT-FAMILY: 宋体">时,通过</span><span lang="EN-US">StartListening()</span><span style="FONT-FAMILY: 宋体">可以把信道设置为监听状态,而通过</span><span lang="EN-US">StopListening()</span><span style="FONT-FAMILY: 宋体">则可以停止对信道的监听。此外,还有一个用于访问所获取的数据的属性</span><span lang="EN-US">ChannelData</span><span style="FONT-FAMILY: 宋体">。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">使用信道类的属性,可以获取信道配置的信息。</span><span lang="EN-US">HTTP</span><span style="FONT-FAMILY: 宋体">信道和</span><span lang="EN-US">TCP</span><span style="FONT-FAMILY: 宋体">信道都有</span><span lang="EN-US">ChannelName</span><span style="FONT-FAMILY: 宋体">属性、</span><span lang="EN-US">ChannelPriority</span><span style="FONT-FAMILY: 宋体">属性和</span><span lang="EN-US">ChannelData</span><span style="FONT-FAMILY: 宋体">属性。使用</span><span lang="EN-US">ChannelData</span><span style="FONT-FAMILY: 宋体">属性可以获取保存在</span><span lang="EN-US">ChannelDataStore</span><span style="FONT-FAMILY: 宋体">类中的</span><span lang="EN-US">URI</span><span style="FONT-FAMILY: 宋体">信息。此外,</span><span lang="EN-US">HttpChannel</span><span style="FONT-FAMILY: 宋体">还有一个</span><span lang="EN-US">Scheme</span><span style="FONT-FAMILY: 宋体">属性。下面的帮助方法</span><span lang="EN-US">ShowChannelProperties()</span><span style="FONT-FAMILY: 宋体">在文件</span><span lang="EN-US">HelloServer.cs</span><span style="FONT-FAMILY: 宋体">中,显示了信道的配置信息:</span></p>
<p class="2" style="MARGIN-TOP: 8.15pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">protected static void ShowChannelProperties(IChannelReceiver channel)</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">{</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp; Console.WriteLine(&quot;Name: &quot; + channel.ChannelName);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp; Console.WriteLine(&quot;Priority: &quot; + channel.ChannelPriority);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp; if (channel is HttpChannel)</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp; {</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HttpChannel httpChannel = channel as HttpChannel;</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(&quot;Scheme: &quot; + httpChannel.ChannelScheme);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp; }</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp; ChannelDataStore data = (ChannelDataStore)channel.ChannelData;</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp; foreach (string uri in data.ChannelUris)</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp; {</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(&quot;URI: &quot; + uri);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp; }</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp; Console.WriteLine();</span></p>
<p class="2" style="MARGIN-TOP: 0cm; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">}</span></p>
<p class="MsoNormal"><span style="COLOR: black; FONT-FAMILY: 宋体">在</span><span lang="EN-US" style="COLOR: black">Main()</span><span style="COLOR: black; FONT-FAMILY: 宋体">方法中,创建信道之后,就调用</span><span lang="EN-US" style="COLOR: black">ShowChannelProperties()</span><span style="COLOR: black; FONT-FAMILY: 宋体">方法。启动服务器就可以得到图</span><span lang="EN-US" style="COLOR: black">16-5</span><span style="COLOR: black; FONT-FAMILY: 宋体">所示的控制台输出信息。</span><span style="FONT-FAMILY: 宋体">从中可以看出,</span><span lang="EN-US">TcpServerChannel</span><span style="FONT-FAMILY: 宋体">的默认名称是</span><span lang="EN-US">tcp</span><span style="FONT-FAMILY: 宋体">,而</span><span lang="EN-US">HTTP</span><span style="FONT-FAMILY: 宋体">信道的默认名称是</span><span lang="EN-US">http</span><span style="FONT-FAMILY: 宋体">。这两个信道的默认优先权都是</span><span lang="EN-US">1</span><span style="FONT-FAMILY: 宋体">,用构造函数设置的端口显示在</span><span lang="EN-US">URI</span><span style="FONT-FAMILY: 宋体">中。信道的</span><span lang="EN-US">URI</span><span style="FONT-FAMILY: 宋体">显示协议、</span><span lang="EN-US">IP</span><span style="FONT-FAMILY: 宋体">地址和端口号。</span></p>
<p class="a6" style="MARGIN-TOP: 8.15pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">TcpServerChannel tcpChannel = new TcpServerChannel(8086);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">ShowChannelProperties(tcpChannel);</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">HttpServerChannel httpChannel = new HttpServerChannel(8085);</span></p>
<p class="2" style="MARGIN-TOP: 0cm; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">ShowChannelProperties(httpChannel);</span></p>
<p align="center"><span lang="EN-US"><img height="119" src="16/image005.jpg" width="209" alt="" /></span></p>
<p style="FTEL: .0001pt" align="center"><span style="COLOR: black; FONT-FAMILY: 宋体">图</span><span lang="EN-US" style="COLOR: black">&nbsp; 16-5</span></p>
<h4 style="FTEL: 21.45pt"><span lang="EN-US">1. </span><span style="FONT-FAMILY: 黑体">设置信道属性</span></h4>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">使用构造函数</span><span lang="EN-US">TCPServerChannel(IDictionary</span><span style="FONT-FAMILY: 宋体">、</span><span lang="EN-US">IServerChannelSinkProvider)</span><span style="FONT-FAMILY: 宋体">,可以在一个列表中设置信道的所有属性。</span><span lang="EN-US">Hashtable </span><span style="FONT-FAMILY: 宋体">类实现</span><span lang="EN-US"> IDictionary</span><span style="FONT-FAMILY: 宋体">,因此,使用这个类可以设置</span><span lang="EN-US">Name</span><span style="FONT-FAMILY: 宋体">属性、</span><span lang="EN-US">Priority</span><span style="FONT-FAMILY: 宋体">属性和</span><span lang="EN-US"> Port</span><span style="FONT-FAMILY: 宋体">属性。为了使用</span><span lang="EN-US">Hashtable</span><span style="FONT-FAMILY: 宋体">类,必须声明使用</span><span lang="EN-US">System.Collections</span><span style="FONT-FAMILY: 宋体">命名空间。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">在类</span><span lang="EN-US">TcpServerChannel</span><span style="FONT-FAMILY: 宋体">的构造函数中,除了参数</span><span lang="EN-US">IDictionary</span><span style="FONT-FAMILY: 宋体">之外,还可以传递实现接口</span><span lang="EN-US">IServerChannelSinkProvider</span><span style="FONT-FAMILY: 宋体">的对象。本例中设置的是</span><span lang="EN-US">SoapServerFormatterSinkProvider</span><span style="FONT-FAMILY: 宋体">而不是</span><span lang="EN-US">BinaryServerFormatterSinkProvider</span><span style="FONT-FAMILY: 宋体">,前者是</span><span lang="EN-US">TcpServerChannel</span><span style="FONT-FAMILY: 宋体">的默认值。</span><span lang="EN-US">SoapServerFormatter SinkProvider</span><span style="FONT-FAMILY: 宋体">类的默认实现把</span><span lang="EN-US">SoapServerFormatterSink</span><span style="FONT-FAMILY: 宋体">类与使用</span><span lang="EN-US">SoapFormatter</span><span style="FONT-FAMILY: 宋体">的信道联系起来,以转换数据,使之能进行传输:</span></p>
<p class="2" style="MARGIN-TOP: 8.15pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">IDictionary properties = new Hashtable();</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; LINE-HEIGHT: 15pt; FTEL: 18.45pt"><span lang="EN-US">properties[&quot;name&quot;] = &quot;TCP Channel with a SOAP Formatter&quot;;</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; LINE-HEIGHT: 15pt; FTEL: 18.45pt"><span lang="EN-US">properties[&quot;priority&quot;] = &quot;20&quot;;</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; LINE-HEIGHT: 15pt; FTEL: 18.45pt"><span lang="EN-US">properties[&quot;port&quot;] = &quot;8086&quot;;</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; LINE-HEIGHT: 15pt; FTEL: 18.45pt"><span lang="EN-US">SoapServerFormatterSinkProvider sinkProvider = </span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; LINE-HEIGHT: 15pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new SoapServerFormatterSinkProvider();</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; LINE-HEIGHT: 15pt; FTEL: 18.45pt"><span lang="EN-US">TcpServerChannel tcpChannel = </span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; LINE-HEIGHT: 15pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new TcpServerChannel(properties, sinkProvider);</span></p>
<p class="2" style="MARGIN-TOP: 0cm; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">ShowChannelProperties(tcpChannel);</span></p>
<p class="MsoNormal" style="LINE-HEIGHT: 17pt"><span style="COLOR: black; FONT-FAMILY: 宋体">服务器的新控制台输出结果显示了</span><span lang="EN-US" style="COLOR: black">TCP</span><span style="COLOR: black; FONT-FAMILY: 宋体">信道的新属性,如图</span><span lang="EN-US" style="COLOR: black">16-6</span><span style="COLOR: black; FONT-FAMILY: 宋体">所示。</span></p>
<p class="MsoNormal" style="LINE-HEIGHT: 17pt"><span style="FONT-FAMILY: 宋体">根据信道的类型,可以指定不同的属性。</span><span lang="EN-US">TCP</span><span style="FONT-FAMILY: 宋体">和</span><span lang="EN-US">HTTP</span><span style="FONT-FAMILY: 宋体">信道都支持本例中使用的</span><span lang="EN-US">name</span><span style="FONT-FAMILY: 宋体">和</span><span lang="EN-US">priority</span><span style="FONT-FAMILY: 宋体">信道属性。这些信道也支持其他属性,例如</span><span lang="EN-US">bindTo</span><span style="FONT-FAMILY: 宋体">,如果计算机配置了多个</span><span lang="EN-US">IP</span><span style="FONT-FAMILY: 宋体">地址,</span><span lang="EN-US">bindTo</span><span style="FONT-FAMILY: 宋体">指定绑定可以使用的</span><span lang="EN-US">IP</span><span style="FONT-FAMILY: 宋体">地址。</span><span lang="EN-US">TCP</span><span style="FONT-FAMILY: 宋体">服务器信道支持</span><span lang="EN-US">rejectRemoteRequests</span><span style="FONT-FAMILY: 宋体">,只允许从本地计算机上连接客户机。</span></p>
<p align="center"><span lang="EN-US"><img height="117" src="16/image006.jpg" width="233" alt="" /></span></p>
<p style="FTEL: 8.15pt" align="center"><span style="COLOR: black; FONT-FAMILY: 宋体">图</span><span lang="EN-US" style="COLOR: black">&nbsp; 16-6</span></p>
<h4 style="FTEL: 21.45pt"><span lang="EN-US">2. </span><span style="FONT-FAMILY: 黑体">信道的&ldquo;可插入性&rdquo;</span></h4>
<p class="MsoNormal" style="LINE-HEIGHT: 17pt"><span style="FONT-FAMILY: 宋体">创建的定制信道可以使用</span><span lang="EN-US">HTTP</span><span style="FONT-FAMILY: 宋体">和</span><span lang="EN-US">TCP</span><span style="FONT-FAMILY: 宋体">之外的其他协议发送消息。此外,也可以对现有的信道进行扩展:</span></p>
<p class="1" style="MARGIN-LEFT: 37.55pt; FTEL: -16.1pt"><span lang="EN-US">●<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-FAMILY: 宋体">发送部分必须实现</span><span lang="EN-US">IChannelSender</span><span style="FONT-FAMILY: 宋体">接口。最重要的部分是</span><span lang="EN-US">CreateMessageSink()</span><span style="FONT-FAMILY: 宋体">方法,在该方法中,客户要发送</span><span lang="EN-US">URL</span><span style="FONT-FAMILY: 宋体">,此外,使用这个方法可以实例化与服务器的连接。在这里必须创建消息接收器,代理对象使用该消息接收器把消息发送到信道中。</span></p>
<p class="1" style="MARGIN-LEFT: 37.55pt; FTEL: -16.1pt"><span lang="EN-US">●<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-FAMILY: 宋体">接收部分必须实现</span><span lang="EN-US">IChannelReceiver</span><span style="FONT-FAMILY: 宋体">接口。必须在</span><span lang="EN-US">ChannelData get</span><span style="FONT-FAMILY: 宋体">属性中启动监听,然后,可以等待一个线程接收来自客户的数据。在对消息进行解组之后,使用</span><span lang="EN-US" style="LETTER-SPACING: -0.2pt">ChannelServices.SyncDispatchMessage()</span><span style="FONT-FAMILY: 宋体">把消息<span style="LETTER-SPACING: -0.2pt">分派给对象。</span></span></p></div>
                <!-- page -->
                <div class="page" style="text-align: center">
                    <a href="100165470.htm">上一页</a>&nbsp;&nbsp;&nbsp;<a href="index.html">首页</a>&nbsp;&nbsp;&nbsp;<a href="100165472.htm">下一页</a>
                </div>
                <div style="margin: 0px auto; width: 700px; border: solid 1px #0b5f98;">
                    <div style="float: left; width: 16px; background-color: #0b5f98; color: White; padding: 1px;">
                        图书导读
                    </div>
                    <div style="float: right; width: 670px; text-align: left; line-height: 16pt; padding-left: 2px">
                        <!--导读-->
                        <h1 id="divCurrentNode2" style="color: #b83507; width: 100%; text-align: left; font-size: 12px; padding-left: 2px">当前章节:<a href='100165471.htm'><font color='red'>16.5.1  信道</font></a></h1>
                        <div id="divRealteNod2" style="padding-left: 2px">
                        <div style='float:left;width:49%'>·<a href='100165468.htm'>16.4.2  简单的服务器</a></div><div style='float:right;width:49%'>·<a href='100165469.htm'>16.4.3  简单的客户机</a></div><div style='float:left;width:49%'>·<a href='100165470.htm'>16.5  .NET Remoting体系结构</a></div><div style='float:right;width:49%'>·<a href='100165472.htm'>16.5.2  格式标识符</a></div><div style='float:left;width:49%'>·<a href='100165473.htm'>16.5.3  ChannelServices和RemotingConfiguration</a></div><div style='float:right;width:49%'>·<a href='100165474.htm'>16.5.4  对象的激活</a></div></div>
                    </div>
                </div>
                </div>
        </div>
</body>
</html>

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?