.Net Remoting to WCF Challenge!

I am trying to port my remote access code in .net to wcf, but it is difficult for me. Can someone help me migrate this simple Remoting-based program below to use WCF? The program implements a simple publisher / subscriber template in which we have one TemperatureProviderProgram program, which is the publisher of many TemperatureSubcriberPrograms programs that subscribe to ThermProvider.

To run programs:

  • Copy the TemperatureProviderProgram and TemperatureSubcriberProgram to separate console application projects.
  • Copy the remaining classes and interfaces into a common class library project, then add a link to the System.Runtime.Remoting library
  • Add a link to the class library project from console application projects.
  • Observe and run 1 TemperatureProviderProgram and several TemperatureSubcriberProgram.

Please note that IIS or xml should not be used. Thanks in advance.

public interface ITemperatureProvider { void Subcribe(ObjRef temperatureSubcriber); } [Serializable] public sealed class TemperatureProvider : MarshalByRefObject, ITemperatureProvider { private readonly List<ITemperatureSubcriber> _temperatureSubcribers = new List<ITemperatureSubcriber>(); private readonly Random randomTemperature = new Random(); public void Subcribe(ObjRef temperatureSubcriber) { ITemperatureSubcriber tempSubcriber = (ITemperatureSubcriber)RemotingServices.Unmarshal(temperatureSubcriber); lock (_temperatureSubcribers) { _temperatureSubcribers.Add(tempSubcriber); } } public void Start() { Console.WriteLine("TemperatureProvider started..."); BinaryServerFormatterSinkProvider provider = new BinaryServerFormatterSinkProvider(); provider.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full; TcpServerChannel tcpChannel = new TcpServerChannel("TemperatureProviderChannel", 5001, provider); ChannelServices.RegisterChannel(tcpChannel, false); RemotingServices.Marshal(this, "TemperatureProvider", typeof(ITemperatureProvider)); while (true) { double nextTemp = randomTemperature.NextDouble(); lock (_temperatureSubcribers) { foreach (var item in _temperatureSubcribers) { try { item.OnTemperature(nextTemp); } catch (SocketException) {} catch(RemotingException) {} } } Thread.Sleep(200); } } } public interface ITemperatureSubcriber { void OnTemperature(double temperature); } [Serializable] public sealed class TemperatureSubcriber : MarshalByRefObject, ITemperatureSubcriber { private ObjRef _clientRef; private readonly Random portGen = new Random(); public void OnTemperature(double temperature) { Console.WriteLine(temperature); } public override object InitializeLifetimeService() { return null; } public void Start() { BinaryServerFormatterSinkProvider provider = new BinaryServerFormatterSinkProvider(); provider.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full; int port = portGen.Next(1, 65535); TcpServerChannel tcpChannel = new TcpServerChannel(string.Format("TemperatureSubcriber_{0}", Guid.NewGuid()), port, provider); ChannelServices.RegisterChannel(tcpChannel, false); ITemperatureProvider p1 = (ITemperatureProvider)RemotingServices.Connect(typeof(ITemperatureProvider), "tcp://localhost:5001/TemperatureProvider"); _clientRef = RemotingServices.Marshal(this, string.Format("TemperatureSubcriber_{0}_{1}.rem", Environment.MachineName, Guid.NewGuid())); p1.Subcribe(_clientRef); } } public class TemperatureProviderProgram { static void Main(string[] args) { TemperatureProvider tp = new TemperatureProvider(); tp.Start(); } } public class TemperatureSubcriberProgram { static void Main(string[] args) { Console.WriteLine("Press any key to start TemperatureSubcriber."); Console.ReadLine(); TemperatureSubcriber ts = new TemperatureSubcriber(); ts.Start(); Console.ReadLine(); } } 
+4
source share
5 answers

You need to change your logic a bit. If you want to port this application to WCF . You will need to force customers to regularly retrieve data from the service.

You will also need a Windows service or application to host WCF , like the console you use in the previous code.

+1
source

In WCF with "push" from the server, you are really talking about duplex communications; MarshalByRefObject is pretty much redundant here (AFAIK). The page here discusses various scenarios, including duplex / callbacks.

If the problem is in xml (for some philosophical reason), then just helping the NetDataContractSerializer , not the DataContractSerializer can help.

Another approach is to periodically β€œpull” customer data; this works well if you need to support basic http etc.

+1
source

It looks like you want to use WCF NetTcpBinding with Callbacks.

Take a look at this: http://www.codeproject.com/KB/WCF/publisher_subscriber.aspx

"WCF Training" Michelle Bustamante is also very good. You can get Chpt1 for VS2008 on your website along with code for the book. Chpt1 will explain / demo setup connections etc. She also has a downloadable sample code. One example is DuplexPublishSubscribe.

+1
source

Well, I'm building real-time systems, so polling is not an option - I need to click data.

Also I find that there is no WCF equivalent of System.Runtime.Remoting.ObjRef! This is an extremely useful type that encapsulates a service endpoint and can be serialized and transmitted over the network to another remote access service.

Think that I will stick to the good old remote action until the ObjRef equivalent is presented.

0
source

Yes, it’s true, only one correction. ObjRefs are created automatically when any derived MarshalByRefObject goes beyond appdomain. So in this case your interface is ITemperatureProvider Subscribe method shoud accept ITemperatureSubscriber instead of objref. And then on the client side, just call p1.Subscribe (this), and the remote layer will generate ObjRef from the object that will be serialized and sent. (sending link b)

0
source

All Articles