国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > 綜合 > 正文

Remoting編程知識一

2024-07-21 02:17:07
字體:
來源:轉載
供稿:網(wǎng)友
remoting基礎


基本原理
當客戶端創(chuàng)建遠程remotableclass的一個實例,.net框架在客戶端應用程序域中產(chǎn)生一個代理。該代理看起來就像實際對象。代理收到調用后,通過通道連接到遠程的對象。



一、編寫步驟

第一步


編寫一個dll,其中包含所要remottable的類

public class remotableclass:marshalbyrefobject

{

….

}




第二步

服務器進程注冊該remotable 類以便其他應用程序可以激活。根據(jù)該對象是如何激活,服務器通過兩種靜態(tài)方法來注冊:registeractivatedservicetype或者registerwellknownservicetype。下面的語句使用registerwellknownservicetype來注冊remotableclass,以便遠程激活。

remotingconfiguration.registerwellknownservicetype(

typeof(remotableclass), //remotable類

“remoteobject”, // remotable類的uri

wellknownobjectmode.singlecall); //激活模式

第一個參數(shù)是指能遠程化的類。

第二個是指客戶端使用來激活對象的uri----也就是客戶端告訴服務器來激活

remotableclass實例的uri。

第三個參數(shù)指定激活模式。有兩種選擇。wellknownobjectmode.singlecall是指為客戶端的每一次調用創(chuàng)建一個新的實例。wellknownobjectmode.singleton是指創(chuàng)建一個remotableclass實例來處理所有客戶端的調用。

第三步

為了使客戶端可以使用remotableclass,服務器進程必須創(chuàng)建,注冊一個通道。該通道提供對象和遠程客戶端交流的一個渠道。在服務器端,.net框架提供了兩種通道:

system.runtime.remoting.channels.tcp.tcpserverchannel:可以接受遠程客戶端的tcp連接。

system.runtime.remoting.channels.http.httpserverchannel:接受http連接。

下面的語句創(chuàng)建一個在1234端口監(jiān)聽的tcpserverchannel通道,并用.net框架注冊:

tcpserverchannel channel = new tcpserverchannel(1234);

channelservices.registerchannel(channel);

下面的語句注冊了一個在1234端口監(jiān)聽的http通道:

httpservicechannel channel = new httpserverchannel(1234);

channelservices.registerchannel(channel);

tcpserverchannel更有效率一點。httpserverchannel是使用iis作為遠程激活代理時使用的選擇。


第四步

在客戶端要想創(chuàng)建遠程類的一個實例,也必須做一些注冊。

第一必須注冊一個客戶端通道。.net框架提供了兩種類型的客戶端通道:tcpclientchannel和httpclientchannel,分別和服務器端通道相對應。

第二,如果客戶端想使用new操作符來生產(chǎn)遠程對象,必須將遠程對象注冊到本地應用程序域。

remotingconfiguration.registerwellknownclienttype是在客戶端注冊一個類。

remotingconfiguration.registerwellknownservicetype是在服務器上注冊一個類。

下面的代碼在客戶端注冊了一個tcp通道,而且也將remotableclass注冊到本地應用程序域中:

tcpclientchannel channel = new tcpclientchannel();

channelservices.registerchannel(channel);



remotingconfiguration.registerwellknownclienttype(

typeof(remotableclass),

“tcp://localhost:1234/remoteobject”);

第二個參數(shù)是指遠程對象的url。

協(xié)議必須匹配應用程序注冊的通道協(xié)議。

可以使用機器名或者ip地址來替換localhost。

端口數(shù)必須好服務器端監(jiān)聽的端口數(shù)一樣。

對象uri,必須和服務器用registerwellknownservicetype注冊的匹配。

第五步

在客戶端使用new來產(chǎn)生代理:

remotableclass rc = new remotableclass();

這個操作在客戶端應用程序域中產(chǎn)生一個代理,返回remotableclass的一個引用。

二、實際范例

clockserver.cs

using system;
public class clock : marshalbyrefobject
{
public string getcurrenttime ()
{
return datetime.now.tolongtimestring ();
}
}
timeserver.cs

using system;
using system.runtime.remoting;
using system.runtime.remoting.channels;
using system.runtime.remoting.channels.tcp;
class myapp
{
static void main ()
{
tcpserverchannel channel = new tcpserverchannel (1234);
channelservices.registerchannel (channel);

remotingconfiguration.registerwellknownservicetype
(typeof (clock), "clock", wellknownobjectmode.singlecall);

console.writeline ("press enter to terminate...");
console.readline ();
}
}
timeclient.cs

using system;
using system.runtime.remoting;
using system.runtime.remoting.channels;
using system.runtime.remoting.channels.tcp;
class myapp
{
static void main ()
{
tcpclientchannel channel = new tcpclientchannel ();
channelservices.registerchannel (channel);

remotingconfiguration.registerwellknownclienttype
(typeof (clock), "tcp://localhost:1234/clock");
clock clock = new clock ();
console.writeline (clock.getcurrenttime ());
}
}
編譯:

1. csc /t:library clockserver.cs
2. csc /r:clockserver.dll timeserver.cs
3. csc /r:clockserver.dll timeclient.cs
要將clockserver.dll拷貝到客戶端。因為創(chuàng)建遠程對象的代理時,.net框架需要描述clock類的原數(shù)據(jù)。它可以從dll中得到原數(shù)據(jù)。



三、配置方式

timeserver和timeclient在其源代碼內部注冊通道和遠程化的類。這樣有個缺點,一旦任何一個注冊數(shù)據(jù)改變,你必須要修改源代碼,并重新編譯。

這就是為什么.net框架支持另一種形式的注冊。聲明注冊是通過調用靜態(tài)

remotingconfiguration.configure方法來從config文件中得到信息。

范例如下:

clockserver.cs

using system;

public class clock : marshalbyrefobject
{
public string getcurrenttime ()
{
return datetime.now.tolongtimestring ();
}
}

timeserver.cs

using system;
using system.runtime.remoting;

class myapp
{
static void main ()
{
remotingconfiguration.configure ("timeserver.exe.config");
console.writeline ("press enter to terminate...");
console.readline ();
}
}
timeserver.exe.config

<configuration>
<system.runtime.remoting>
<application>
<service>
<wellknown mode="singlecall" type="clock, clockserver"
objecturi="clock" />
</service>
<channels>
<channel ref="tcp server" port="1234" />
</channels>
</application>
</system.runtime.remoting>
</configuration>
timeclient.cs

using system;
using system.runtime.remoting;

class myapp
{
static void main ()
{
remotingconfiguration.configure ("timeclient.exe.config");
clock clock = new clock ();
console.writeline (clock.getcurrenttime ());
}
}
timeclient.exe.config

<configuration>
<system.runtime.remoting>
<application>
<client>
<wellknown type="clock, clockserver"
url="tcp://localhost:1234/clock" />
</client>
<channels>
<channel ref="tcp client" />
</channels>
</application>
</system.runtime.remoting>
</configuration>
該方式的缺點是配置文件可以被修改和刪除。


四、激活方式

.net框架將可遠程化對象分為兩種:服務器激活對象和客戶端激活對象。服務器端激活對象是通過remotingconfiguration’sregisterwellknownservicetype和

registerwellknownclienttype方法注冊的。上面的范例都是服務器端激活對象。客戶端激活對象是通過registeractivateservicetype和registeractivatedclienttype注冊的。



服務器端激活對象被稱為服務器激活的,因為當客戶端使用new,只有一個代理被創(chuàng)建。實際對象知道通過代理來調用一個方法時才被創(chuàng)建(激活)。換句話說,不是客戶端決定什么時候去創(chuàng)建物理上的真正對象??蛻舳思せ顚ο笤诳蛻舳耸褂胣ew時就在服務器上創(chuàng)建。這個是第一個差別。

第二個差別是客戶端激活對象可以使用非缺省構造函數(shù)(帶參數(shù)的構造函數(shù))激活。服務器端機會對象不支持非缺省構造函數(shù),因為使用new只是創(chuàng)建一個代理,并沒有創(chuàng)建對應的實際對象??蛻舳思せ顚ο罂梢酝ㄟ^new同時創(chuàng)建代理和對象。

第三個差別是客戶端和對象是如何聯(lián)系在一起的。當注冊服務器激活對象時,你可以指定激活模式來決定為每一個請求創(chuàng)建一個對象實例還是創(chuàng)建一個對象實例來服務所有的請求。這兩中激活模式是:

wellknownobjectmode.singlecall:為每個請求創(chuàng)建一個唯一的對象實例。

wellkonwnobjectmode.singleton:創(chuàng)建一個對象實例來服務所有的請求

通常根據(jù)環(huán)境來選擇合適的激活模式。舉例來說,如果一個遠程化對象提供了一個”one-shot”服務,不需要在多次調用間保持狀態(tài)或者不需要在所有客戶端同享狀態(tài),那么singlecall是個正確的選擇。因為每一次的請求產(chǎn)生的是一個新的對象實例。如果想在客戶端之間傳遞數(shù)據(jù),則要使用singleton。

singleton對象一個值得注意的地方是線程的同步問題。當兩個客戶端同時調用該對象的方法時,可能會出現(xiàn)錯誤,這時要使用.net框架提供的同步機制。



客戶端激活對象提供第三種選擇。當使用客戶端激活對象時,該對象僅為此客戶端服務,可以在多次調用間保持狀態(tài)。



single-call服務器激活對象,singleton服務器激活對象和客戶端激活對象的提供了三種不同的激活模式。當不需要在所有客戶端共享狀態(tài)時,則使用single-call。當要在所有客戶端共享狀態(tài)時則使用singleton。當不需要所有的客戶端連接到同一個對象,只要保持該客戶端自己的狀態(tài)時,則使用客戶端激活對象。



程序范例:

stopwatch.cs

using system;
public class stopwatch : marshalbyrefobject
{
datetime mark = datetime.now;
public void start ()
{
mark = datetime.now;
}
public int stop ()
{
return (int) ((datetime.now - mark).totalmilliseconds);
}
}
stopwatchserver.cs

using system;
using system.runtime.remoting;
using system.runtime.remoting.channels;
using system.runtime.remoting.channels.tcp;
class myapp
{
static void main ()
{
tcpserverchannel channel = new tcpserverchannel (1234);
channelservices.registerchannel (channel);

remotingconfiguration.registeractivatedservicetype
(typeof (stopwatch));

console.writeline ("press enter to terminate...");
console.readline ();
}
}
stopwatchclient.cs

using system;
using system.runtime.remoting;
using system.runtime.remoting.channels;
using system.runtime.remoting.channels.tcp;
class myapp
{
static void main ()
{
tcpclientchannel channel = new tcpclientchannel ();
channelservices.registerchannel (channel);
remotingconfiguration.registeractivatedclienttype
(typeof (stopwatch), "tcp://localhost:1234");
stopwatch sw = new stopwatch ();
sw.start ();
console.writeline ("press enter to show elapsed time...");
console.readline ();
console.writeline (sw.stop () + " millseconds");
}
}
五、activator.getobject和activator.createinstance方法

new操作符并不是激活遠程對象的唯一方法。.net框架提供了其他的激活方法:getobject和createinstance。它們都是system.activator類的成員。getobject被用來激活在服務器端激活的對象,而createinstance被用來激活在客戶端激活的對象。

當使用getobject或者createinstance來激活遠程對象時,不再需要調用registeractivatedclienttype或者registerwellknownclienttype來注冊服務器上可遠程化的類。例如:激活在服務器端激活的對象時:

remotingconfiguration.registerwellknownclienttype(typeof(clock),”tcp://localhost:1234/clock”);

clock clock = new clock();

可以使用下面的方法代

clock clock =(clock) activator.getobject(typeof(clock,”tcp://localhost:1234/clock”);

激活客戶端對象時:

remotingconfiguration.registeractivatedclienttype(typeof(stopwatch),”tcp://localhost:1234”);

stopwatch sw = new stopwatch();

可以這樣的方式:

object[] url ={new urlattribute(“tcp://localhost:1234”)};

stopwatch sw =(stopwatch) activator.createinstance(typeof(stopwatch),null,url);

為什么要使用它們來代替new呢?因為在你僅知道url和接口時,getobject和createinstance可以仍使用。假設改變clock類,它實現(xiàn)一個iclock接口。

使用getobject時:

iclock ic = (iclock)activator.getobject(typeof(iclock),”tcp://localhost:1234/clock”);

如果使用new,則會出現(xiàn)編譯錯誤,因為new不能接受一個接口名稱:

remotingconfiguration.registerwellknownclienttype
(typeof (iclock), "tcp://localhost:1234/clock");
iclock ic = new iclock ();



六、對象生存期和租用期

一個single-call服務器端激活對象只在方法調用期間生存。之后,被垃圾回收器標記為刪除。singleton 服務器激活對象和客戶端激活對象不一樣,他們的生存期被租用控制。租用是一個對象,它實現(xiàn)了定義在system.runtime.remoting.lifetime名稱空間的ilease接口。

singleton 服務器端激活對象和客戶端激活對象缺省的租用對象有一個5分鐘的initialleasetime,2分鐘的renewoncalltime,5分鐘的currentleasetime。如果對象沒有方法被調用,當currentleasetime為0時它被清除,也就是5分鐘后被清除。



最大的網(wǎng)站源碼資源下載站,

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 府谷县| 登封市| 上饶县| 祥云县| 临洮县| 辽阳县| 玉屏| 泊头市| 游戏| 祁阳县| 浏阳市| 永年县| 灵武市| 广平县| 唐山市| 九江县| 射阳县| 柳林县| 读书| 城固县| 冕宁县| 滕州市| 鸡西市| 凤翔县| 泸溪县| 宝应县| 禄丰县| 达拉特旗| 卢氏县| 武川县| 濉溪县| 安龙县| 凤翔县| 朝阳区| 东阳市| 精河县| 景泰县| 青龙| 白沙| 曲阜市| 尼勒克县|