Hello! For those who are interested in Remoting, here is a summary of the current status:
* The basic Remoting infrastructure (channels, sinks and all this) is not finished, but it is complete enough for testing. Since RemotingConfiguration is not yet finished, use RemotingServices.Marshal to publish an object, and Activator.GetObject() to get an object form a server. * The TcpChannel is working, but it is currently not compatible with MS' tcp channel. * BinaryFormatterProvider is also working. All formatting is done by BinaryFormatter, which is quite complete. It can serialize complex parameters and return values, including arrays, enums and delegates. * Marshalling and unmarshalling of MarshalByRefObject instances is working, so you can pass object references between applications. Delegates are not working with MBR objects due to a problem with virtual methods and transparent proxy. I think Patrik is working to solve this (and many other things!) I've prepared simple an example of a client application that connects to an object in a server application and calls some methods. I think it is the better way to show you what can remoting do and how to do it. To test it, compile like this: mcs -t:library ServerObject.cs mcs -r:ServerObject.dll -r:System.Runtime.Remoting.dll RemotingClient.cs mcs -r:ServerObject.dll -r:System.Runtime.Remoting.dll RemotingServer.cs Enjoy ! Lluis.
using System; using System.Net; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; namespace RemotingTest { class RemotingClient { static void Main () { TcpChannel ch = new TcpChannel(0); ChannelServices.RegisterChannel (ch); // This gets the object from the server (a list of ServerObject) Console.WriteLine("Getting instance ..."); object remOb = Activator.GetObject(typeof(ServerList),"tcp://localhost:1122/test.rem"); ServerList list = (ServerList)remOb; // These are remote calls that return references to remote objects Console.WriteLine ("Creating two remote items..."); ServerObject item1 = list.NewItem ("Created at server 1"); item1.SetValue (111); // another call made to the remote object ServerObject item2 = list.NewItem ("Created at server 2"); item2.SetValue (222); Console.WriteLine (); // Two objects created in this client app Console.WriteLine ("Creating two client items..."); ServerObject item3 = new ServerObject ("Created at client 1"); item3.SetValue (333); ServerObject item4 = new ServerObject ("Created at client 2"); item4.SetValue (444); Console.WriteLine (); // Object references passed to the remote list Console.WriteLine ("Adding items..."); list.Add (item3); list.Add (item4); Console.WriteLine (); // This sums all values of the ServerObjects in the list. The server // makes a remote call to this client to get the value of the // objects created locally Console.WriteLine ("Processing items..."); list.ProcessItems (); Console.WriteLine (); // Passing some complex info as parameter and return value Console.WriteLine ("Setting complex data..."); ComplexData cd = new ComplexData (AnEnum.d, new object[] {"some",22,"info"}); ComplexData res = list.SetComplexData (cd); Console.WriteLine ("This is the result:"); res.Dump(); Console.WriteLine (); list.Clear(); Console.WriteLine ("Done."); ch.StopListening (null); } } }
using System; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; namespace RemotingTest { class RemotingServer { static int Main () { Console.WriteLine("Starting Server"); TcpChannel ch = new TcpChannel(1122); ChannelServices.RegisterChannel (ch); ServerList ser = new ServerList(); RemotingServices.Marshal(ser,"test.rem"); Console.WriteLine("Server Running ..."); Console.ReadLine(); ch.StopListening (null); return 0; } } }
using System; using System.Runtime.Remoting; using System.Collections; namespace RemotingTest { // A list of ServerObject instances public class ServerList: MarshalByRefObject { ArrayList values = new ArrayList(); public void Add (ServerObject v) { values.Add (v); System.Console.WriteLine ("Added " + v.Name); } public void ProcessItems () { System.Console.WriteLine ("Processing..."); int total = 0; foreach (ServerObject ob in values) total += ob.GetValue(); System.Console.WriteLine ("Total: " + total); } public void Clear() { values.Clear(); } public ServerObject NewItem(string name) { ServerObject obj = new ServerObject(name); Add (obj); return obj; } public ComplexData SetComplexData (ComplexData data) { System.Console.WriteLine ("Showing content of ComplexData"); data.Dump (); return data; } } // A remotable object public class ServerObject: MarshalByRefObject { int _value; string _name; public ServerObject (string name) { _name = name; } public string Name { get { return _name; } } public void SetValue (int v) { System.Console.WriteLine ("ServerObject " + _name + ": setting " + v); _value = v; } public int GetValue () { System.Console.WriteLine ("ServerObject " + _name + ": getting " + _value); return _value; } } // Some complex data for testing serialization public enum AnEnum { a,b,c,d,e }; [Serializable] public class ComplexData { public AnEnum Val = AnEnum.a; public object[] Info; public ComplexData (AnEnum va, object[] info) { Info = info; Val = va; } public void Dump () { System.Console.WriteLine ("Content:"); System.Console.WriteLine ("Val: " + Val); foreach (object ob in Info) System.Console.WriteLine ("Array item: " + ob); } } }