VS2008 .Net 3.5 Remoting程式設計入門三

iDotNetSpace發表於2009-05-13

通道

什麼是通道?通道有哪些型別呢?

通道顧名思意就是通訊的通道。就想那些宣傳標語說的,“要想富,先修路!”。同理,要學習Remoting,當然要學習通道了。

.NET Framework 遠端處理基礎結構提供下列通道實現:

IpcChannel

TcpChannel

HttpChannel

IpcChannel

IpcChannel 類使用命名管道為同一臺計算機上的多程式應用程式提供高速程式間通訊。IpcChannel 執行下列功能:

使用命名管道在傳送方和接收方之間通訊。

支援以二進位制格式和行業標準 SOAP 序列化格式編碼負載。

生成並使用物件引用的 ChannelDataStore

支援模擬和委託。

支援在命名管道上利用訪問控制列表 (ACL) 來提供高階訪問控制。

當一個應用程式必須與同一臺計算機上其他程式中執行的另一個應用程式通訊時,就應當使用 IpcChannel。由於 IpcChannel 使用命名管道,因此應用程式通常能夠獲得最高的通訊效能,並可以使用模擬和委託來控制對遠端物件的訪問。對於三層應用程式而言,其第二層和第三層之間的通訊必須能夠在負載下執行良好。此時,這一功能便尤其有用。

TcpChannel

TcpChannel 類使用二進位制格式化程式將所有訊息序列化為二進位制流,並使用 TCP 協議將該流傳輸至目標統一資源識別符號 (URI)TcpChannel 執行下列功能。

使用 TCP 套接字在傳送方和接收方之間通訊。

支援以二進位制格式和行業標準 SOAP 序列化格式編碼負載。

生成並使用物件引用的 ChannelDataStore

支援模擬和委託。

支援 SSPI 加密。

TcpChannel 會根據該時刻向另一臺伺服器傳送請求的執行緒數開啟並快取相應數目的連線。當套接字連線的非活動時間超過 15-20 秒後,客戶端將關閉這些連線。

在生成大量使用 .NET Framework 遠端處理的應用程式時,很容易錯誤地使用 HttpChannel 連線至用 TcpChannel 進行偵聽的伺服器應用程式域。如果建立了這種連線,客戶端將收到以下異常:基礎連線已經關閉: 接收時發生錯誤。如果您的客戶端收到此異常,則應當檢查客戶端和伺服器,以確定是否存在通道不匹配的問題。

HttpChannel

HttpChannel 類使用 SOAP 協議在遠端物件之間傳輸訊息。所有訊息都通過 SoapFormatter 傳遞,此格式化程式會將訊息轉換為 XML 並進行序列化,同時向資料流中新增所需的 SOAP 標頭。如果還指定了二進位制格式化程式,則會建立二進位制資料流。隨後,將使用 HTTP 協議將資料流傳輸至目標 URIHttpChannel 符合 SOAP 1.1 標準,它執行下列功能:

通過將 HTTP 協議用作傳輸在傳送方和接收方之間通訊。

支援以 SOAP(一種 XML 編碼標準)和二進位制格式編碼負載。

將接收方設定為通過 ASP.NET TCP 套接字接收 HTTP 請求併傳送 HTTP 響應。

生成並使用物件引用的 ChannelDataStore

支援模擬和委託。

支援 SSPI 加密。

HttpChannel 一次只向給定伺服器開啟指定數目的連線。預設值為 2,但您可以使用應用程式配置檔案中的 clientConnectionLimit 屬性更改該預設值。

在生成大量使用 .NET Framework 遠端處理的應用程式時,很容易錯誤地使用 HttpChannel 連線至用 TcpChannel 進行偵聽的伺服器應用程式域。如果建立了這種連線,客戶端將收到以下異常:基礎連線已經關閉: 接收時發生錯誤。如果您的客戶端收到此異常,則應當檢查客戶端和伺服器,以確定是否存在通道不匹配的問題。

以上摘自MSDN,已經說的很明白了。

 

每種型別的channel都有對應的clientchannelserverchannel兩中形式。在一般情況下,我們直接使用一種型別的channel,負責接受和傳送。

下面看看程式碼怎麼寫的。

 

遠端物件類,RemotingClass.cs和以前的一樣,不要改變。

using System;

namespace RemotingClass

{

    public class Message : MarshalByRefObject

    {

        public Guid MessageId { get; set; } //Guid,用於儲存Message的ID

        public Message()

        {

            this.MessageId = Guid.NewGuid();//當物件被例項同時產生一個ID

        }

 

        public delegate void MessageHandler(string msg);

        public static event MessageHandler OnSendMessage;

        public void SendMessage(string msg)

        {

           if (OnSendMessage != null)

                OnSendMessage("Message的ID是:" + this.MessageId + msg);

        }

    }

}

服務端程式碼:(注意看註釋的地方)

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Runtime.Remoting;

using System.Runtime.Remoting.Channels;

using System.Runtime.Remoting.Channels.Ipc;//使用IpcChannel

//using System.Runtime.Remoting.Channels.Http;//使用HttpChannel

//using System.Runtime.Remoting.Channels.Tcp;//使用TcpChannel

 

 

namespace Server

{

    class Program

    {

        static void Main(string[] args)

        {

            Console.WriteLine("Host Started!");

            //HttpChannel channel = new HttpChannel(20001);//建立HttpChannel通道

            //TcpChannel channel = new TcpChannel(20001);//建立TcpChannel通道

            IpcChannel channel = new IpcChannel("localhost:20001");//建立IpcChannel通道,和http、tcp有點不一樣,其他的地方基本一樣。

 

            ChannelServices.RegisterChannel(channel, false);

            RemotingConfiguration.RegisterWellKnownServiceType(typeof(RemotingClass.Message), "Message.rem", WellKnownObjectMode.SingleCall); //這裡使用SingleCall即可

            RemotingClass.Message.OnSendMessage += new RemotingClass.Message.MessageHandler(Message_OnSendMessage);

            Console.Read();

        }

        public static void Message_OnSendMessage(string msg)

        {

            Console.WriteLine(msg);

        }

    }

}

 

客戶端程式碼:(注意看註釋的方法)

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Runtime.Remoting;

using System.Runtime.Remoting.Channels;

using System.Runtime.Remoting.Channels.Ipc;

//using System.Runtime.Remoting.Channels.Http;//使用HttpChannel

//using System.Runtime.Remoting.Channels.Tcp;//使用TcpChannel

 

namespace Client

{

    class Program

    {

        static void Main(string[] args)

        {

            Console.WriteLine("Client Started!");

            // HttpChannel channel = new HttpChannel();//建立HttpChannel通道

            // TcpChannel channel = new TcptChannel();//建立TcpChannel通道

            IpcChannel channel = new IpcChannel();//建立IpcChannel通道

            ChannelServices.RegisterChannel(channel, false);

            RemotingConfiguration.RegisterWellKnownClientType(typeof(RemotingClass.Message), "ipc://localhost:20001/Message.rem");

//注意此處的協議,不同的通道使用不同的協議。如果是httpchannel,則使用http,如果是tcpchannel,則請使用tcp

            RemotingClass.Message msg = new RemotingClass.Message();

            while (true)

            {

                msg.SendMessage(" 現在是:" + System.DateTime.Now.ToString());

                System.Threading.Thread.Sleep(2000);

            }

            //Console.ReadLine();

        }

 

    }

}

原文地址:http://www.cnblogs.com/xray2005/archive/2008/11/22/1339202.html

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-594972/,如需轉載,請註明出處,否則將追究法律責任。

相關文章