我們先花20分鐘做一個簡單的remoteing的例子。
首先我們建立一個dll的remoteing遠程對象,這個對象有點類似於EJB裡面的介面檔案的功能,但是又不完全只是負責通訊,我們會把商務邏輯也寫在這個介面裡面:
建立1個類庫項目RemoteObject:
using System;
namespace RemoteObject
{
public class MyObject:MarshalByRefObject
{
public int Add(int a,int b)
{
return a+b;
}
public string str()
{
return "i am come from server:";
}
}
}
編譯一下。
接著建立伺服器端程式RemoteServer:
using System;
using System.Runtime.Remoting;
namespace RemoteServer
{
class MyServer
{
[STAThread]
static void Main(string[] args)
{
RemotingConfiguration.Configure("RemoteServer.exe.config");
Console.ReadLine();
}
}
}
並添加一個設定檔App.config:
<configuration>
<system.runtime.remoting>
<application name="RemoteServer">
<service>
<wellknown type="RemoteObject.MyObject,RemoteObject" objectUri="RemoteObject.MyObject"
mode="Singleton" />
</service>
<channels>
<channel ref="tcp" port="9999"/>
</channels>
</application>
</system.runtime.remoting>
</configuration>
將剛才編譯好的dll檔案考到建立的伺服器程式的bin目錄下,添加引用,編譯伺服器程式。
建立用戶端程式RemoteClient:
using System;
namespace RemoteClient
{
class MyClient
{
[STAThread]
static void Main(string[] args)
{
RemoteObject.MyObject remoteclient = (RemoteObject.MyObject)Activator.GetObject(typeof(RemoteObject.MyObject),System.Configuration.ConfigurationSettings.AppSettings["ServiceURL"]);
Console.WriteLine(remoteclient.str()+remoteclient.Add(1,2));
Console.ReadLine();
}
}
}
建立用戶端程式的設定檔App.config:
<configuration>
<appSettings>
<add key="ServiceURL" value="tcp://localhost:9999/RemoteObject.MyObject"/>
</appSettings>
</configuration>
將剛才編譯好的dll檔案考到建立的用戶端程式的bin目錄下,添加引用,編譯伺服器程式。
先運行伺服器程式,然後在運行用戶端程式,可以看到如下介面:
現在我們完成了一個簡單的remoteing執行個體,他和EJB同樣是實現異地通訊,但是我們現在看看他和EJB有什麼不同:
1.remoteing事務寫在dll(即介面),ejb寫在伺服器。
2.伺服器程式相當於EJB裡面的容器,可以裝載N個實現業務的介面,通過對設定檔裡面的通道類型,連接埠號碼,介面名字的設定,確定用戶端程式訪問哪一個dll.
3.通過客戶段啟用和伺服器啟用的例子也可以知道,雖然完成的業務是在dll裡面寫好了,但實際上申請的空間和業務所使用的記憶體空間是在伺服器裡面,dll對象會通過自己的建構函式去使用伺服器程式在伺服器端構造一些記憶體位址,以及存放變數或者其他函數的空間,所以dll的業務操作並不是在用戶端。
所以由此也可知道,實現事務所在的記憶體位址實際上是在伺服器上面。
(感謝lovecherry的blog,我的文章裡面加入了一些自己的理解和思考,如果大家想看到純淨版的remoting請看http://www.cnblogs.com/lovecherry,不敢掠人之美。)