Introduction
This article is a merger of MVC architecture and .NET remoting using HTTP and TCP channel. The server is nothing but an executable that acts as a container of controller, model and local view. Individual views are running with their discrete on local or remote computers and they have proxies of remote server controller and model.
How It Works
Activating the server will create the local view, controller and model objects. It registers controller and model objects for remote purposes. The server starts listening on HTTP and TCP ports. In this code sample, all port numbers are hard coded that can be modified to make it dynamic. Server side controller and model proxies will be marshaled to client on specific channel with specific formatters using special IConnect
object. IConnect
is something that acts as a connector between client and server. Client activates IConnect
object in the server and takes the proxy object of controller and model through IConnect
.
Client-Server Communication
When the client starts, it tries to connect to the server and activates the IConnect
object at server. IConnect
is a singleton type object and if multiple clients try to connect, it will pass the same object proxy to each client. Once IConnect
object proxies are marshalled to server, the client can access proxies of the controller and model by calling properties (get
-set
) of IConnect
.
All the UI events either from server or from client go to the controller on the server. The controller on the server updates the model if required. Once the model is updated, it updates all the views (server + clients views) using delegate
s. If any client is not registered with a delegate
, it will not receive broadcast update messages from the model.
Lease time and server client disconnectivities are not covered in this article. If the user wants, he can derive InitializeLifetimeService()
of MarshalByRefObject
class and can modify lease time.
All Clients are statically programmed to connect to localhost server in this sample code. The user can modify localhost with remote IP address and the code will work fine.
Using the Code
The following is the server boot up routine that:
- Registers channels (HTTP and TCP)
- Registers remote objects (
Connect
, Controller
and Model
) - Displays local UI
BinaryClientFormatterSinkProvider clientProvider = null;
BinaryServerFormatterSinkProvider serverProvider =
new BinaryServerFormatterSinkProvider();
serverProvider.TypeFilterLevel =
System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;
IDictionary props = new Hashtable();
props["port"] = 3870;
props["typeFilterLevel"] = TypeFilterLevel.Full;
TcpChannel tcpChannel = new TcpChannel(
props, clientProvider, serverProvider);
ChannelServices.RegisterChannel(tcpChannel);
props.Clear();
props = new Hashtable();
props["port"] = 3970;
props["typeFilterLevel"] = TypeFilterLevel.Full;
SoapClientFormatterSinkProvider scl = null;
SoapServerFormatterSinkProvider ssr = new SoapServerFormatterSinkProvider();
ssr.TypeFilterLevel = TypeFilterLevel.Full;
HttpChannel httpChannel = new HttpChannel(props, scl, ssr);
ChannelServices.RegisterChannel(httpChannel);
RemotingConfiguration.RegisterWellKnownServiceType(
typeof(windowConnect),
"Window Connect", WellKnownObjectMode.Singleton);
RemotingConfiguration.RegisterWellKnownServiceType(
typeof(windowController),
"Window Controller", WellKnownObjectMode.Singleton);
RemotingConfiguration.RegisterWellKnownServiceType(
typeof(windowModel),
"Window Model", WellKnownObjectMode.Singleton);
wndController = new windowController();
theForm1 = new Form1();
theForm1.WindowController = wndController;
theForm1.WindowModel = wndModel;
theForm1.UpdateFromServer();
Application.Run(theForm1);
Following is the client activation code that:
- Registers channel (HTTP or TCP)
- Registers own view
- Activates
IConnect
object - Accesses proxy of controller and model remotely
BinaryClientFormatterSinkProvider clientProvider = null;
BinaryServerFormatterSinkProvider serverProvider =
new BinaryServerFormatterSinkProvider();
serverProvider.TypeFilterLevel =
System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;
IDictionary props = new Hashtable();
props["port"] = 0;
props["typeFilterLevel"] = TypeFilterLevel.Full;
TcpChannel tcpChannel = new TcpChannel(
props, clientProvider, serverProvider);
ChannelServices.RegisterChannel(tcpChannel);
RemotingConfiguration.RegisterWellKnownServiceType(
typeof(IView),
"Window View", WellKnownObjectMode.Singleton);
Form1 theForm = new Form1();
IConnect windowConnect;
try
{
windowConnect = (IConnect)Activator.GetObject(typeof(IConnect),
"tcp://localhost:3870/Window Connect");
windowConnect.RegisterView(theForm);
theForm.WindowController = windowConnect.ProxyController;
theForm.WindowModel = windowConnect.ProxyModel;
}
catch (Exception e)
{
MessageBox.Show("Server not running. Link cannot be established");
return;
}
The following code is used by both client and server programs. It contains the base classes of view, controller, model and connect.
namespace MVCInterface
{
public delegate void updateRadius();
public class IView:System.Windows.Forms.Form
{
public updateRadius updateRadiusEvent;
}
public abstract class IController:MarshalByRefObject
{
public abstract void AnotherRadiusChange(int radius);
}
public abstract class IModel:MarshalByRefObject
{
private int radius=12;
public int Radius
{
get { return radius; }
set { radius = value; }
}
public abstract void RadiusChange(int radius);
}
public abstract class IConnect:MarshalByRefObject
{
public abstract void RegisterView(IView proxyView);
private IController _proxyController=null;
public IController ProxyController
{
get { return _proxyController; }
set { _proxyController = value; }
}
private IModel _proxyModel=null;
public IModel ProxyModel
{
get { return _proxyModel; }
set { _proxyModel = value; }
}
}
}
Points of Interest
I learned a lot about .NET remoting and MVC architecture with the implementation of this article.
History
- 30th July, 2007: Initial post
About Myself
Hi I am Vikas working on Microsoft technologies for last 2.5 yrs. Currently working with Tektronix,India as a Senior software Engineer. I have worked in Bharat Electronics, India also for 2 yrs.
mailme@maan_vikas@rediffmail.com
Vikas Maan is a software developer for last 4 years working on windows platform with multiple programming languages mainly VC++, C#.net etc.