. Net Remoting is a distributed communication technology framework launched by Microsoft earlier. It is widely used in. Net architecture programs. In WCF, Remoting technology has been integrated. However, they share many similar concepts, such as Channel, Proxy, and host. There are still some distributed system applications running systems built by Remoting technology. This article describes their implementation methods in the interaction between the server and the client.
1. Implementation of Remoting.
In Remoting, remote objects are an important concept. The server registers it to the specified channel. The client server publishes the URI of the remote object registered by the server and uses it through a proxy. In this architecture, the server and client need to communicate with each other by event.
The Remoting communication model consists of three parts: 1. Client, 2. Remote Object, 3. Host Program (the application domain hosted by the server ).
Note: remote objects generally inherit from MarshalByRefObject, while objects inherited from MarshalByRefObject do not leave their application domains. For security purposes, we generally provide interfaces implemented by remote objects to clients, rather than remote objects.
1. The client sends a message to the server.The client obtains the proxy for the remote object. After using the interface provided by the client, the remote object is transmitted through the channel. After receiving a message, the remote object uses an event to perform corresponding operations on the server. At this time, the event is defined in a remote object. After the client performs an operation, the server can directly obtain the message by subscribing to the event of the remote object.
2. the server sends a message to the client.On the server, because it is an application domain registered with a remote object, the server can directly use it. Similarly, the server sends messages to the client through events. Unlike the client that actively sends messages to the server, events defined as remote objects run on the server and cannot be serialized to the client. In this case, we can generally perform operations in a way similar to "intermediary.
The Remoting program structure is as follows:
Note:
- Client: the Client program. Build a Winform project for visibility
- CommandAssembly: public assembly. It is a class library shared between the client and the server. It includes the Interface Definition of remote object implementation.
- Host: A server program, that is, an application hosted by a remote object. It is also a Winform Project
- RemoteObject: a remote object.
First, let's look at the Interface Definition of remote object implementation:
/// <Summary> /// event when the server notifies the client /// </summary> event DataChangeCallBack DataChangeEventHandler; /// <summary> /// server-side event trigger function // </summary> /// <param name = "entityName"> </param> void ServerSideDataChange (string entityName ); /// <summary> // The client calls the interface function used by the server // </summary> /// <param name = "entityName"> </param> void ClientSideDataChange (string entityName );
Second, remote object definition:
Public class RemoteObject: callback, IDataChange {public event DataChangeCallBack callback; # region IDataChange member public void ServerSideDataChange (string entityName) {if (condition = null) return; foreach (Delegate datachange in DataChangeEventHandler. getInvocationList () {DataChangeCallBack tem P = datachange as DataChangeCallBack; try {temp (entityName);} catch {DataChangeEventHandler-= temp ;}} public void ClientSideDataChange (string entityName) {if (expiration! = Null) {ClientDataChangeEventHandler (entityName) ;}# endregion public override object InitializeLifetimeService () {return null ;}}
Note: In the remote object display, rewrite the InitializeLifetimeService function of the base class to ensure that the remote object never expires. This involves the remote object lifecycle. If you are interested, you can find out (in memory, the lifetime of remote objects is 6 minutes ). If you do not rewrite this function, an error will occur if another client wants to obtain its proxy through URI after the remote object is recycled by GC. Because it has already been recycled by GC.
Next, let's look at the definition of the "intermediary" object used when the server notifies the client:
Public class EventWrapper: externalbyrefobject, IDataChange {public event DataChangeCallBack DataChangeEventHandler; # region IDataChange member public void ServerSideDataChange (string entityName) {if (response! = Null) {DataChangeEventHandler (entityName) ;}} public void ClientSideDataChange (string entityName) {}# endregion}
Finally, there is a problem with the server and client channels, event registration, and message sending. The client implementation is mainly provided here (because of issues related to the server Event Notification client ). The server is similar.
private void ClientForm_Load(object sender, EventArgs e) { UnregisterChannels(); RegisterChannel(); RegisterEvent(); } void UnregisterChannels() { if (ChannelServices.RegisteredChannels.Length == 0) { return; } foreach (IChannel channel in ChannelServices.RegisteredChannels) { ChannelServices.UnregisterChannel(channel); } } void RegisterChannel() { IDictionary hashtable = new Hashtable(); hashtable["port"] = 0; BinaryClientFormatterSinkProvider provider = new BinaryClientFormatterSinkProvider(); TcpChannel tcpChannel = new TcpChannel(hashtable, provider, null); ChannelServices.RegisterChannel(tcpChannel, true); } void RegisterEvent() { instance = Activator.GetObject(typeof(IDataChange), "tcp://127.0.0.1:8888/DataService") as IDataChange; wrapper = new EventWrapper(); wrapper.DataChangeEventHandler+=new DataChangeCallBack(wrapper_DataChangeEventHandler); instance.DataChangeEventHandler += wrapper.ServerSideDataChange; } void wrapper_DataChangeEventHandler(string entityName) { if (txtReceiveMsg.InvokeRequired) { txtReceiveMsg.Invoke(new ShowMessageCallBack(wrapper_DataChangeEventHandler), entityName); } else { txtReceiveMsg.Text = entityName; } } private void btnSend_Click(object sender, EventArgs e) { if (!string.IsNullOrEmpty(txtSendMsg.Text)) { instance.ClientSideDataChange(txtSendMsg.Text); } }
The program running interface is as follows:
Server:
Client:
Note: The corresponding formatted identifier should be used in the Channel Definition.
2. Implementation of WCF
In WCF, communication between the server and the client is generally conducted in duplex mode. In WCF, dual binding protocols are supported: netTcpBinding and wsDualHttpBingding. In the example of server-Client Communication implemented by WCF, select the previous protocol.
The program structure is as follows:
Similarly, for visualization, the Host and Client are also Winform programs.
In the implementation of WCF, the implemented functions are identical to those of Remoting.
First, let's look at the service contract definition:
[ServiceContract(CallbackContract=typeof(ICallBack))] public interface IDataChange { [OperationContract(IsOneWay=true)] void Register(); [OperationContract(IsOneWay=true)] void ServerSideDataChange(string entityName); [OperationContract(IsOneWay = true)] void ClientSideDataChange(string entityName); }
Callback contract definition:
public interface ICallBack { [OperationContract(IsOneWay=true)] void DataChange(string entityName); }
Service implementation code:
[ServiceBehavior (InstanceContextMode = InstanceContextMode. single, ConcurrencyMode = ConcurrencyMode. single)] public class DataService: IDataChange {public event DataChangeCallBack extends eclientdatachangehandler; ICallBack callBack; # region IDataChange member public void Register () {callBack = OperationContext. current. getCallbackChannel <ICallBack> ();} public void ServerSideDataChange (string entityName) {CallBack. DataChange (entityName);} public void ClientSideDataChange (string entityName) {if (ReceiveClientDataChangeHandler! = Null) {effececlientdatachangehandler (entityName) ;}# endregion}
The boarding code of the Service in Winform is as follows:
Private void ServerFrom_Shown (object sender, EventArgs e) {Thread thread = new Thread (ServiceStart); thread. start ();} void ServiceStart () {Uri address = new Uri ("net. tcp: // 127.0.0.1: 8806/DataService "); using (ServiceHost host = new ServiceHost (service, address) {host. open (); tipStatus. text = "the service has been started"; while (true) {Thread. sleep (100 );}}}
On the client side, the callback interface is directly implemented through the form. The form is encapsulated in InstanceContext to make the form object the object of the callback operation on the server side. When the server calls back the client, the information is directly sent to the form. Make the following definitions in the FormLoad event of the client form:
InstanceContext context = new InstanceContext(this); dataChange = new ClientProxy(context); dataChange.Register();
The client notifies the server in a simple way, that is, actively calling the service interface. The Code is as follows:
if (!string.IsNullOrEmpty(txtSendMsg.Text)) { dataChange.ClientSideDataChange(txtSendMsg.Text); }
In this way, when the client calls the server interface, a server event is triggered to notify the form to display data.
When the service notifies the client, it calls back the client to send messages to the client. The Code is as follows:
Form.cs
if (!string.IsNullOrEmpty(txtSendMsg.Text))
{
service.ServerSideDataChange(txtSendMsg.Text);
}
//DataSerive.cs
public void ServerSideDataChange(string entityName)
{
callBack.DataChange(entityName);
}
In this way, the communication between the server and the client is realized in the WCF architecture.
The running interface is similar to the preceding one. It is not repeated.
Code: http://files.cnblogs.com/tyb1222/Project.rar