What is .NET Remoting?
.NET Remoting is a Microsoft application programming interface (API) for inter process
communication. The framework provides a number of services, including activation and lifetime
support, as well as communication channels responsible for transporting messages to and from
remote applications. Formatters are used for encoding and decoding the messages before they are
transported by the channel. Applications can use binary encoding where performance is critical,
or XML encoding where interoperability with other remoting frameworks is essential. All XML
encoding uses the SOAP protocol in transporting messages from one application domain to the
other.
How does Remoting work?
One of the main objectives of any remoting framework is to provide the necessary infrastructure
that hides the complexity of calling methods on remote objects and returning results. All local
objects that have to cross the application domain boundary have to be passed by value and
should be marked with the [Serializable] custom attribute. Any object can be changed into a
remote object by deriving it from MarshalByRefObject. When a client activates a remote
object, it receives a proxy to the remote object. All operations on this proxy are directed to the
remote object.
HTTP Channel
The HTTP channel transports messages to and from remote objects using the SOAP protocol. All
messages are passed through the SOAP formatter, where the message is serialized into and the
required SOAP headers are added to the stream. It is also possible to configure the HTTP
Channel to use the binary formatter. The resulting data stream is then transported to the target
URI using the HTTP protocol.
TCP Channel
The TCP channel uses a binary formatter to serialize all messages to a binary stream and
transport the stream to the target URI using the TCP protocol. It is also possible to configure the
TCP channel to use the SOAP formatter.
A. Create a console application named RemotingServer and add a class called Employee and
do the following on the Employee class.
01. The Employee class should contain employee number, name, basic salary, EPF amount,
overtime amount, overtime hours and the balance payment as attributes. You can create
them as public attributes. (Note: Or create them as private attributes and add getters and
setters for each attribute).
02. Make sure that you mark this class as [Serializable] since we want to pass an Employee
object to the client side.
03. Rewrite the parameterless Employee constructor, so that it would just print “Employee
created”. In this way we can identify which application (client or server) creates the
Employee object.
04. Write a method named printName to print the employee’s name to the output console.
Using this method we can test which application (client or server) executes this method.
//Employee.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace RemotingServer
{
[Serializable]
class Employee
{
public string
empNumber;
public string name;
public double
basicSalary;
public double
epfAmount;
public double
otAmount;
public double
otHours;
public double
balancedPayment;
public Employee()
{
Console.WriteLine("Employee created ");
}
public void
printName()
{
Console.WriteLine(name);
}
}
}
B. Now add another class called SalaryApp and do the following on the SalaryApp class.
01. Make the class extend from MarshalByRefObject. This will allow the clients to create SalaryApp objects remotely as remote objects.
02. Rewrite the parameterless SalaryApp constructor, so that it would just print “Client connected”. In this way we can identify which application (client-locally or server-remotely) creates the SalaryApp object.
03. Write a method named CreateEmployee which accepts employee number, name, basic salary and overtime hours as input parameters. Create an Employee object in this method and initialize the employee number, name basic salary and overtime hours, using the values received as input parameters. You can initialize the other variables to 0.
04. Now write a method named calEPF which will return nothing but will calculate the EPF amount of the employee and print it.
05. Write a method named calOT which will return nothing but will calculate the overtime amount of the employee and print it.
06. Write a method named calBalancePay which will calculate balance pay for the employee, print it and returns the Employee object itself. (Note: Use following formulas for the calculations. Overtime amount = overtime hours * 750 , balance pay = basic salary + overtime amount – EPF amount)
important
SalaryApp calss shoud be public
//SalaryApp.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace RemotingServer
{
public class SalaryApp:MarshalByRefObject
{
Employee e1;
public SalaryApp()
{
}
public SalaryApp(string
eno, string ename, double
sal, double othrs)
{
Console.WriteLine("Server
object was created");
e1 = new Employee();
e1.empNumber = eno;
e1.name = ename;
e1.basicSalary = sal;
e1.otHours = othrs;
e1.epfAmount = 0;
e1.otAmount = 0;
}
public void calEPF(double basicSal)
{
e1.epfAmount = basicSal * 0.08;
}
public void calOT(double ot)
{
e1.otAmount = ot * 750;
}
public double
calBalancePay(double basicSal, double ot)
{
double balPay;
calEPF(basicSal);
calOT(ot);
balPay = e1.basicSalary + e1.otAmount - e1.epfAmount;
return balPay;
}
public string
empName()
{
return e1.name;
}
}
}
C. Now in the main program, add the .NET Remoting configurations.
01. First add the below .NET remoting reference to the application which is required for remoting configurations.
System.Runtime.Remoting
02. Create a TcpChannel object with a specific port (Ex: 8001). An example is given below.
TcpChannel channel = new TcpChannel(8001);
03. All remote objects have to be registered with the remoting framework before clients can access them. Object registration is normally done by a hosting application that starts up, registers one or more channels with ChannelServices, registers one or more remote objects with RemotingConfiguration, and then waits until it is terminated. Let’s use Client Activated Method to register the client. An example is given below.
ChannelServices.RegisterChannel(channel,false);
RemotingConfiguration.RegisterActivatedServiceType(typeof(SalaryApp));
04. Also we want our server to be up & running and listening for incoming client requests without terminating instantly. Use the following code segment for this purpose.
Thread.Sleep(Timeout.Infinite);
//Programmm.cs
namespace RemotingServer
{
class Program
{
static void Main(string[] args)
{
//Registration using Client Activated metheod
//IChannel channel = new TcpChannel(8001); also possible
TcpChannel tcp = new
TcpChannel(8001);
ChannelServices.RegisterChannel(tcp, false);
// as client activated
//RemotingConfiguration.RegisterActivatedServiceType(typeof(SalaryApp));
//as server activated
RemotingConfiguration.RegisterWellKnownServiceType(typeof(SalaryApp),
"Server", WellKnownObjectMode.SingleCall);
//To hold the program
//Can use Thread.Sleep(Timeout.Infinite); also
Console.ReadLine();
}
}
}
Exercise 02: Creating the client
A. Now create a Windows Forms application named RemotingClient and design a form according to the figure 01. Follow the steps and create the client application.
Figure 01
01. First add a reference to the server’s EXE in the client application. By doing this client application will be able to understand the server implementation details such as classes and methods.
02. Add the remoting reference to the client application also, since it is required for registration.
System.Runtime.Remoting
03. When the Connect to Server button is clicked, invoke the SalaryApp constructor and create a SalaryApp object remotely, which is on the remote server side.
04. When the Create Employee button is clicked, use the SalaryApp object created above and invoke the createEmployee method of the SalaryApp. Pass the values of the text boxes entered by the user, as parameter values to the method.
05. When the Calculate OT Amount button is clicked, invoke the calOT method of the SalaryApp class.
06. When the Calculate EPF Amount button is clicked, invoke the calEPF method of the SalaryApp class
.
07. When Calculate Balance Pay button is clicked, invoke the getBalncePay method of the SalaryApp class and display the balance pay in the label 6.
08. When Print Employee Name button is clicked, invoke the printName method of the Employee class.
B. Now in the main program we will add the .NET Remoting configurations for the client. Let’s use Client Activated Method to register the client.
string sURL = "tcp://localhost:8001";
RemotingConfiguration.RegisterActivatedClientType
(typeof(RemotingServer.salaryApp),sURL);
Note that this should be done executed client clicks any buttons. Else the server object would be created locally. Think of a suitable place to include this code, so that remoting will be performed as expected!
important
You should add reference ServerRemoting.exe
//Programm.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Runtime.Remoting;
using RemotingServer;
namespace RemotingClient
{
static class Program
{
/// <summary>
/// The main entry point
for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new
Form1());
string sURL = "tcp://localhost:8001";
RemotingConfiguration.RegisterActivatedClientType(typeof(SalaryApp),
sURL);
}
}
}
//Form coding
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using RemotingServer;
namespace RemotingClient
{
public partial class Form1 : Form
{
SalaryApp sa;
public Form1()
{
InitializeComponent();
}
private void
button1_Click(object sender, EventArgs e)
{
sa = new SalaryApp(textBox1.Text,textBox2.Text,Convert.ToDouble(textBox3.Text),Convert.ToDouble(textBox4.Text));
}
private void
button2_Click(object sender, EventArgs e)
{
sa = new SalaryApp(textBox1.Text,
textBox2.Text, Convert.ToDouble(textBox3.Text),
Convert.ToDouble(textBox4.Text));
}
private void
button3_Click(object sender, EventArgs e)
{
sa.calOT(Convert.ToDouble(textBox4.Text));
}
private void
button4_Click(object sender, EventArgs e)
{
sa.calEPF(Convert.ToDouble(textBox3.Text));
}
private void
button5_Click(object sender, EventArgs e)
{
label6.Text = Convert.ToString(sa.calBalancePay(Convert.ToDouble(textBox3.Text), Convert.ToDouble(textBox4.Text)));
}
private void
button6_Click(object sender, EventArgs e)
{
label6.Text = sa.empName();
}
}
}
0 comments:
Post a Comment