Foreword: About Remoting, I have written a few articles. For the knowledge you are currently, it is almost about the basics of Remoting. Now I am preparing to advance from the advanced use of Remoting. Then there is a need to organize the learning and work made by the previous period, let alone the article you wrote because of its own knowledge, there is a self-contradictory, so you can also make changes to it. I hope that you have a lot of students.
First, Remoting Foundation
What is remoting, in short, we can see it as a distributed processing method. From the perspective of Microsoft's product point, it can be said that Remoting is an upgrade of DCOM, which improves a lot of functions and is extremely integrated into the .NET platform. Microsoft® .NET Remoting provides a framework that allows objects to interact with another object via an application domain. This is why we use removeing. why? In a Windows operating system, it is separate into a separate process. This process forms a boundary around the application code and the data. If you do not use the inter-process communication (RPC) mechanism, the code executed in a process cannot access another process. This is an operating system to protect the application. However, in some cases, we need to cross the application domain, communicate with additional application domains, that is, cross the boundary.
In Remoting is a communication between the two application domains through the channel. as the picture shows:
First, the client accesss the channel through Remoting to obtain the server object, and then analyze the client object by proxy. This provides a possibility that the server object is published in a service manner. Remote object code can run on the server (such as object activation objects and client activation objects), and then the client is connected to the server through the Remoting connection server and runs in the client through serialization.
In Remoting, for objects to be passed, the designer does not need to know the format of the packet in addition to the type of channel needs to be understood. However, it must be noted that the client is not a real server object when obtaining a server-side object, but a reference to it. This ensures loose coupling of the client and server-side objects, and also optimizes the performance of communication.
1, Remoting two channels
There are two main channels of Remoting: TCP and HTTP. In .NET, System.Runtime.Remoting.Channel interface defines the iChannel interface. The IChannel interface includes TCPChannel channel types and HTTP channel types. They correspond to these two types of Remoting channels, respectively.
The TCPChannel type is placed in the namespace system.Runtime.Remoting.Channel.TCP. The TCP channel provides a Socket-based transmission tool that uses the TCP protocol to span the REMOTING boundary transmission serialized message stream. TCPChannel Type The two-feed format serialized message object default, so it has higher transmission performance. The httpchannel type is placed in the namespace system.Runtime.Remoting.Channel.http. It provides an HTTP protocol to enable it to cross the firewall transmission serialization message stream on the Internet. By default, the HTTPChannel type uses the SOAP format serialized message object, so it has better interoperability. Usually in the local area network, we use TCPChannel; if you want to cross the firewall, use httpchannel.
2. Activation of remote objects
Before accessing an object instance of the remote type, you must create it through a process called Activation and initialize. This client creates a remote object through the channel, called an object activation. In Remoting, the activation of remote objects is divided into two categories: server-side activation and client activation. (1) The server is activated, and it is called WellkNow mode, and many of them are translated as well-known objects. Why is a well-known object activation mode? This type is published because the server application will publish this type before activating the object instance (URI). The server process then configures a WellkNown object for this type and publishes an object based on the specified port or address. .NET Remoting The server-side activation is divided into Singleton mode and SINGLECALL mode.
Singleton mode: This is a state mode. If set to Singleton activation, Remoting will create the same object instance for all clients. When the object is active, the Singleton instance processes all subsequent client access requests, regardless of them are the same client, or other clients. The Singleton instance will remain in the method call. For example, if a remote object has an accumulation method (i = 0; i), multiple clients (eg, two) are called. If set to Singleton mode, the first customer obtains a value of 1, and the second customer obtains a value of 2 because the object instance they get is the same. If you are familiar with the status management of ASP.NET, we can think it is an Application status.
SINGLECALL mode: SingleCall is a stateless mode. Once set to SINGLALL mode, the Remoting will create a remote object instance for each client when the client calls the remote object, and is automatically managed by GC. In the same way, the two customers who access the remote object are 1. We can still learn from the status management of ASP.NET, think it is a SESSION state.
(2) The client is activated. Unlike the WellkNown mode, Remoting will assign a URI when activating each object instance. Once the client activation mode obtains a client's request, an instance reference will be created for each client. SingleCall mode and client activation mode are different: First, the time created by the object instance is different. The client activation method is to instantiate the client once issued a call; while SingleCall is to wait until the calling object method is created. Second, the SINGLECALL mode activation is stateless, and the management of the object life is managed by GC, while the client activated object is status, and its lifecycle can be customized. Third, two activation modes are different in the server side and the client implementation. Especially in the client, SingleCall mode is activated by getObject (), which calls the object's default constructor. The client activation mode is activated by CREATEINSTANCE (), which can pass parameters, so you can call the custom constructor to create an instance.
Second, the definition of the remote object
As mentioned earlier, the client is not a practical server object when obtaining a server-side object, but a reference to it. So in Remoting, there are some must-definition specification for remote objects to follow.
Since Remoting passed objects are referenced by reference, the transmitted remote object classes must inherit MarshalByrefObject. MSDN's instructions for MarshalByrefObject are: MarshalByrefObject is the base class of objects that communicate with the application domain boundaries by using the proxy switched message. Objects are not inherited from MarshalByrefObject to be encapsulated in implicit mode. When the remote application references a value-enclosed object, the copy of the object will be passed across the remote processing boundary. Because you want to communicate with a proxy method instead of a copy method, you need to inherit MarshallByrefObject. The following is a definition of a remote object class:
public class ServerObject: MarshalByRefObject {public Person GetPersonInfo (string name, string sex, int age) {Person person = new Person (); person.Name = name; person.Sex = sex; person.Age = age; return person;} } This class only implements the easiest way to set the basic information of a person and return a Person class object. Note that the Person class returned here. Since Person transmitted here is completed in a pass value, the Remoting requires the reference to the reference, so you must serialize the PERSON class.
Therefore, in remote objects in Remoting, if you want to call or pass an object, such as classes, or structures, the class or structure must implement serialization Attribute [SerializableAttribute].
[Serializable] public class persourn () {public person () {}
Private string name; private string sex; private int agent;
Public string name {get {return name;} set {name = value;}}
Public string sex {get {returnis;} set {sex = value;}}
Public int agent {get {return age;} set {agure
Compile the remote object in a class library into a DLL. This DLL will be placed on the server side and the client to add a reference.
Remote objects that can be passed in Remoting can be various types, including complex DataSet objects as it can be serialized. Remote objects can also include events, but the server side is more special for the process of events. This article does not involve.
Third, server side
According to the first part, depending on the activation mode, the implementation method of different server-side of the channel type is also different. In general, the server should be divided into three steps:
1, registration channel
To communicate across the application domain, channels must be implemented. As mentioned earlier, Remoting provides an IChannel interface that includes two types of TCPChannel and HttpChannel. In addition to performance and serialized data, the implementation is exactly the same, so we will take TCPChannel as an example. Register TCPChannel, first add a reference "System.Runtime.Remoting" in the project, then use the namespace: system.Runtime.Remoting.channel.tcp. code show as below:
TCPChannel Channel = New Tcpchannel (8080); ChannelServices.registerChannel (Channel); Channel (CHANNEL);
When instantiating the channel object, the port number is passed as a parameter. Then call the static method registerchannel () to register the channel object.
2, registration remote object
After registering the channel, you must activate the remote object, you must register the object in the channel. Depending on the activation mode, the method of the registration object is also different.
(1) SINGLETON mode
For WellkNown objects, you can implement: RemotingConfiguration.regiSterwellknownServiceType () by static method:
RemotingConfiguration.registerWellkNownServiceType (TypeOf (ServerRemoteObject.serverObject), "ServiceMessage", WellkNownObjectMode.singleton;
(2) SingleCall mode
The method of the registration object is basically the same as the Singleton mode, just need to change the enumerated parameters WellkNownObjectMode to SingleCall.
RemotingConfiguration.registerwellknownServiceType (TypeOf (ServerRemoteObject.serverObject), "ServiceMessage", WellkNownObjectMode.singlecaLL);
(3) Client activation mode
For the client activation mode, the method used is different, but the difference is not large, and it will be at a glance.
RemotingConfiguration.ApplicationName = "ServiceMessage"; RemotingConfiguration.registeractiVatedServiceType (TypeOf (ServerRemoteObject.serverObject);
Why set the ApplicationName property before registering an object method? In fact, this attribute is the URI of the object. For WellkNown mode, the URI is in the parameter of the RegisterWellkNownServiceType () method, of course, can also be assigned to the ApplicationName property specifically. In the overload of the RegisteractiVatedServiceType () method, there is no parameter for ApplicationName, so you must separate.
3, logout channel
If you want to turn off the Remoting service, you need to log out of the channel or close the monitoring of the channel. In Remoting When we registered the channel, the channel is automatically opened. If the channel is closed, the channel cannot accept the client's request, but the channel still exists. If you want to register again, it will throw an exception. // Get the currently registered channel; ichannel [] channels = channelchannels;
// Turn off the channel named myTCP; Foreach (Ichannel Eachchannel In ChannelS) {if (Eachchannel.ChannelName == "MyTCP") {Tcpchannel Tcpchannel = (TCPChannel) Eachchannel;
// Close the listener; tcpChannel.stoplistence (null);
// Waple the channel; ChannelServices.unregisterChannel (TCPChannel);}} code, the RegisterDChannel attribute is a currently registered channel. In Remoting, it is allowed to register multiple channels at the same time, which will be described later.
Fourth, the client
The client is mainly two things, one is the registration channel. This can be seen from the figure, and the server side and clients in Remoting must pass the message through the channel to obtain a remote object. The second step is to obtain the remote object.
1, registration channel:
TCPCHANNEL CHANNEL = New Tcpchannel (); ChannelServices.RegisterChannel (CHANNEL);
Note that when the client is instantiated, it is the default constructor called, that is, the port number is not passed. In fact, this port number is not possible, but its designation is placed behind a part of the URI.
2, get a remote object.
As with the server side, different activation mode determines that the client's implementation will also be different. However, this difference is only the difference between the WellkNown activation mode and the client activation mode, and the client's implementation is exactly the same for Singleton and SingleCall mode.
(1) Wellknown activation mode
To get a well-known remote object in the server, get the getObject () method of the ACTIVATOR process:
ServerRemoteObject.serverObject ServerObj = (ServerRemoteObject.serverObject) Activator.getObject (TypeOf (ServerRemoteObject.serverObject), "TCP: // localhost: 8080 / serviceMessage");
First activation with WellkNown mode, the client gets the object to use GetObject (). The first parameter is the type of remote object. The second parameter is the server-side URI. If it is an HTTP channel, it is natural to use http: // localhost: 8080 / serviceMessage. Because I use a local machine, so this is localhost, you can use the specific server IP address instead of it. The port must be consistent with the port of the server. Later, the remote object service name defined by the server, that is, the content of the ApplicationName property. (2) Client activation mode
As mentioned earlier, WellkNown mode can only call the default constructor when the client creates an object, and the code above illustrates this, because the getObject () method cannot pass the parameters of the constructor. The client activation mode can create a remote object by a custom constructor.
There are two ways to activate the client activation mode:
1) Call the static method of RemotingConfiguration regiSteractiVatedClientType (). This method returns the value of Void, which only registers the remote object in the client. The specific instantiation also needs to call the constructor of the object class.
RemotingConfiguration.RegisterActivatedClientType (typeof (ServerRemoteObject.ServerObject), "tcp: // localhost: 8080 / ServiceMessage"); ServerRemoteObject.ServerObject serverObj = new ServerRemoteObject.ServerObject ();
2) Call the CREATEINSTANCE () method of the process Activator. This method creates method parameters specify class objects. It is different from the front portObject () that it is to call constructor on the client, and getObject () is just a subject, and the creation instance is done at the server side. The CreateInstance () method has a lot of overload, I am focused on two commonly used. A, Public Static Object CreateInstance (Type Type, Object [] Args, Object [] ActivationAttributes); Parameter Description: Type: The type of object to be created. Args: Array with parameters, sequence, and types of parameters to call constructor. If Args is an empty array or a space reference (Nothing in Visual Basic), the call does not have a constructor for any parameters (default constructor). ActivationAttributes: An array that contains one or more properties that can participate in activation.
The parameter args here is an Object [] array type. It can pass parameters in the constructor to create objects. From here, you can get a conclusion that the remote object class passed by the WellkNown activation mode can only use the default constructor; and the ActiVated mode can customize the constructor. The ActivationAttributes parameter is usually used in this method to transfer the URL of the server.
Suppose our remote object class ServerObject has a constructor:
ServerObject (String PName, String Psex, Int page) {name = pname; sex = psex; agent
Then the code implemented is: object [] attrs = {new urlattribute ("tcp: // localhost: 8080 / serviceMessage")}; object [] objs = new object [3]; objs [0] = "waYfarer"; Objs [1] = "Male"; Objs [2] = 28; serverRemoteObject.serverObject = activator.createInstance (ServerRemoteObject.serverObject), objs, attrs); It can be seen that the OBJS [] array passes is the parameter of constructor. .
B, Public Static ObjectHandle CreateInstance (String asmblyName, String TypeName, Object [] ActivationAttribute;
Parameter Description: AssemblyName: The name of the assembly of the type named TypenAme will be found. If AssemblyName is an empty reference (Nothing in Visual Basic), search for the assembly being executed. TypeName: The name of the preferred type. ActivationAttributes: An array that contains one or more properties that can participate in activation.
The parameter statement is at a glance. Note that this method returns the value of the ObjectHandle, so the code is different from:
object [] attrs = {new UrlAttribute ( "tcp: // localhost: 8080 / EchoMessage")}; ObjectHandle handle = Activator.CreateInstance ( "ServerRemoteObject", "ServerRemoteObject.ServerObject", attrs); ServerRemoteObject.ServerObject obj = (ServerRemoteObject .ServerObject) handle.unwrap ();
This method is actually called the default constructor. ObjectHandle.Unwrap () method is to return to the packaged object.
Note: To use Urlattribute, you will need to add: use system.Runtime.Remoting.actiVation;
Five, Remoting Basics Supplements
By the above description, a simplest Remoting program has been completed. This is a standard to create a Remoting program. However, in the actual development process, we encounter the situation in the case, if you only master a so-called "standard", you can "a trick, eat all over the sky", It is impossible.
1, register multiple channels
In Remoting, multiple channels are allowed at the same time, ie, different channels are created according to different ports. However, Remoting requires the name of the channel to be different because it is used as a unique identifier for the channel. Although Ichannel has a CHANNELNAME attribute, this attribute is read-only. Therefore, the method of creating channels described above cannot achieve the requirements of simultaneous registration of multiple channels.
This time, we must use the interface IDictionary System.Collection in: IDictionary tcpChannelProp = new Hashtable (); tcpChannelProp [ "name"] = "Tcp8080"; tcpChannelProp [ "port"] = 8080; IChannel channel = new TcpChannel (tcpChannelProp NEW
SOAPCLIENTFORMATTERSINKPROVIDER (), New SOAPSERVERFORMATTERSINKPROVIDER ()); ChannelServices.RegisterChannel (Channel);
In the Name property, you can define different channel names.
2, remote object metadata correlation
Since both server-side and clients use remote objects, the usual mode is to generate two identical objects DLLs, add references separately. However, for the safety of code, it is necessary to change this approach to this way for the security of code, and reduce the relevance of remote object metadata. That is, the remote object is implemented on the server, and the metadata of these implementations is deleted on the client.
Due to the different activation mode, the method of creating objects in the client is also different, so the correlation of metadata should be separated, and it should be divided into two cases.
(1) Wellknown activation mode:
Implemented by an interface. On the server side, provide the implementation of the interface and the specific class, and only the interface is provided at the client:
Public Interface iServerObject {Person getPersonInfo (String Name, String Sex, Int Age);}
Public Class ServerObject: MarshalByrefObject, iServerObject {......}
Note: The name of the object set on both sides must be the same, strictly, is the name of the namespace must be the same. (2) Client activation mode:
As mentioned earlier, for the client activation mode, the use of a static method or using the CreateInstance () method must instantiate the client call constructor. So, the remote object we provide at the client, you can't only provide an interface, and there is no class implementation. In fact, it is necessary to separate from the remote object metadata, can be selected by two methods:
a, use the WellkNown activation mode to simulate the client activation mode:
The method is to use the "abstract factory" in the design mode, the following class chart describes the overall solution:
We add the interface and implementation classes of the abstract factory in the remote object of the server:
Public Interface iServerObject {Person getPersonInfo (String Name, String Sex, Int Age);}
Public interface iServerObjfactory {iServerObject CreateInstance ();
public class ServerObject: MarshalByRefObject, IServerObject {public Person GetPersonInfo (string name, string sex, int age) {Person person = new Person (); person.Name = name; person.Sex = sex; person.Age = age; return person }} Public class serverobjfactory: MarshalByrefObject, iServerObjfactory {public iServerObject createInstance () {return new serverObject ();}}
Then only the factory interface and the original object interface are provided in the remote object:
Public Interface iServerObject {Person getPersonInfo (String Name, String Sex, Int Age);}
Public interface iServerObjfactory {iServerObject CreateInstance ();
We use the Wellknown activation mode to register the remote object, on the server side:
// Pass the object; RemotingConfiguration.regiSterwellkNownServiceType (TypeF (ServerRemoteObject.serverobjFactory), "ServiceMessage", WellknownObjectMode.singlecaLL);
Note that the SERVEROBJECT class object is not registered here, but the ServerObjFactory class object.
Client:
ServerRemoteObject.IServerObjFactory serverFactory = (ServerRemoteObject.IServerObjFactory) Activator.GetObject (typeof (ServerRemoteObject.IServerObjFactory), "tcp: // localhost: 8080 / ServiceMessage");
ServerRemoteObject.iserverObject Serverobj = ServerFactory.createInstance ();
Why is this a simulation of a client activation mode? From the perspective of activation, we use the SingleCall mode to activate the object, but activated is not the remote object we have to pass, but the factory object. If the client wants to create a remote object, you should also be obtained through the CreateInstance () method of the factory object. And this method is in the client call. Therefore, its implementation is equivalent to the client activation mode.
b, use alternative classes to replace the metadata of the remote object
In fact, we can use a trick to deceive Remoting. The alternative here is this Trick. Since it is a service, the details of remote objects transmitted by Remoting are of course placed on the server. And copying the object on the client, but because the client must call the constructor, the helpless move taken. Since the specific implementation is on the server side, in order to instantiate the client, then these is good at the client. As for the details of the implementation, it is not used. If the remote object has a method, the server side provides method implementation, and the client provides this method to OK, as for the implementation, you can throw an exception, or return a null value; if the method returns void, then Can be empty. The key is that this client class object has this method. The implementation of this method is similar to the declaration of the method, so I said it is a trick. Methods, such as the constructor is also the case.
Still use code to illustrate this "conspiracy", more intuitive:
Service-Terminal:
Public Class ServerObject: MarshalByrefObject {public serverObject () {}
Public Person getPersonInfo (String Name, String Sex, Int Age) {Person Person = New Person (); Person.Name = Name; Person.sex = SEX; Person.age = age; Return Person;}}
Client:
Public Class ServerObject: MarshalByrefObject {public serverobj () {throw new system.notimplementException ();
Public Person getPersonInfo (String Name, String Sex, Int Age) {throw new system.notimplementException ();}}
Compare the client and server, the client's method getPersonInInInInInfo (), there is no specific implementation details, just throwing an exception. Or directly write the statement Return Null, so that OK. We call the client's alternative class for remote objects.
3, implement the configuration file
The method described above is done with the server URI, port, and the setting of the activation mode. In fact, we can also set it with a configuration file. Doing this is good because this profile is an XML document. If you need to change the port or other, we don't need to modify the program and recompile, but only you need to change this configuration file.
(1) The configuration file of the server side:
If it is a client activation mode, the WellkNown is changed to ActiVated and the Mode property is deleted.
Place this configuration file into the server program's application folder, named serverRemoting.config. Then, the previous server-side program can use this statement directly: RemotingConfiguration.configure ("ServerReming.config");
(2) Client configuration file
If it is the client activation mode, the modification is the same. Call is also using the RemotingConfiguration.configure () method to call the configuration file stored on the client.
The configuration file can also be placed in Machine.config. If the client program is a web application, you can put it in Web.config.
4, start / close the specified remote object
There is no method similar to UnregisterWellkNownServiceType () in Remoting, that is, once the remote object is registered, the object is existing in the channel if there is no closing channel. As long as the client activates the object, an object instance is created. If only one remote object is transmitted, this does not have problems, and it is possible to turn off the channel. If multiple remote objects are transmitted? What should I close the specified remote object? What should I start after the shutdown?
We noticed the Marshal () and disconnect () methods in Remoting, and the answer is here. The MARSHAL () method is to convert the MarshalByrefObject class object to an Objref class object, which is a storage generated agent to communicate with remote object communication. This allows the instance to be serialized in order to transfer between the application domain and over the network, and the client can call. The disconnect () method will open the specific instance object from the channel.
Methods as below:
First registration channel: tcpchannel channel = New Tcpchannel (8080); ChannelServices.registerChannel (CHANNEL);
Then start the service:
First instantiate the remote object on the server side. ServerObject Obj = new serverObject ();
Then, register this object. Note that it doesn't have to use RemotingConfiguration.RegisterWellkNownServiceType (), but use remoteservices.Marshal ():
Objref Objrefwellknown = RemotingServices.Marshal (Obj, "ServiceMessage"); if you want to log out of the object, removeservices.disconnect (obj);
Note that the class object of Disconnect must be an object of the previous instantiated object. Because of this, we can create a specified remote object as needed, and when it is turned off, the object is instantiated before disconnect.
As for the client's call, the same method as the front WellkNown mode, is still available through activator.getObject (). However, from implementation of the code, we will notice a problem, because the server side is explicitly instantiated a remote object, so whether it is the same remote object regardless of the client, they call all the same remote object. Therefore, we will call this method as the simulated Singleton mode.
Client activation mode
We can also simulate client activation mode via marshal () and disconnect (). First we review the "Remote Object Data Correlation" section, in this section, I said the "Abstract Factory" using the design mode to create an object instance to simulate the client activation mode with SingleCall mode. Think about the Singleton mode of the previous simulation. Is it the answer to it?
In the "Simulated Singleton" mode, we use the specific remote object instance Marshal to allow the client to get the reference information of the object. Then we change your idea, when we provide an interface with an abstract factory, the factory class implements the method of creating a remote object. Then we create a factory class instance at the server side. Then, this factory class instance will be Marshal. When the client gets an object, it is not a specific remote object, but obtains a specific factory object. The CREATEINSTANCE () will then create a specific remote object instance. At this time, for multiple clients, calling the same factory class object; however, the remote object is created at each client, so for remote objects, it is activated by the client, and the creation is different. Object.
When we want to start / close the specified object, you only need to use the disconnet () method to log out of the factory class object.
Sixth, small knot
Microsoft.Net Remoting can really be said to be profound. The entire remoting content is not what I can do this. It is not what I can master this Remoting beginner. Wang Guoda wrote in the book "Human Vocabulary": Ancient and modern business university, must pass three realms. "Yesterday, the West is withered, alone on the high building, looking for the end of the earth." This first realm is also. "The belt is gradually widening, and I caught people." This second realm is also. "The crowd is looking for him thousands of Baidu, and it will look back, but the man is in a dim light." This third realm is also. If you describe my study, it is still in the "alone on the high-rise building, I hope to the end of the earth", I can really say that I have not retired.
Perhaps the "wearing belt is getting width", learn that "the end does not regret", "can be" looked back ".