In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article mainly shows you the "Microsoft .net Remoting basic sample analysis", the content is easy to understand, clear, hope to help you solve your doubts, the following let the editor lead you to study and learn the "Microsoft .net Remoting basic sample analysis" this article.
I. Foundation of Remoting
What is Remoting? in short, we can think of it as a distributed processing method. From the Microsoft product point of view, it can be said that Remoting is an upgrade of DCOM, which improves a lot of functions and is well integrated into the .net platform. Microsoft .NET Remoting provides a framework that allows objects to interact with another object through the application domain. That's why we use Remoting. Why? In the Windows operating system, applications are separated into separate processes. This process forms a boundary around the application code and data. Without the interprocess communication (RPC) mechanism, code executed in one process cannot access another process. This is a mechanism that the operating system protects the application. In some cases, however, we need to cross the application domain and communicate with another application domain, that is, across boundaries.
In Remoting, the communication of objects between two application domains is realized through channel. As shown in the figure:
First, the client accesses the channel to get the server object through Remoting, and then parses it to the client object through the proxy. This provides the possibility of publishing server objects as a service. The remote object code can be run on the server (such as server-activated objects and client-activated objects), and then the client connects to the server through Remoting to get the service object and run it on the client through serialization.
In Remoting, for the object to be passed, the designer does not need to know the format of the packet other than the type of channel and port number. However, it must be noted that when the client gets the server-side object, it does not get the actual server-side object, but gets its reference. This not only ensures the loose coupling of client-side and server-side related objects, but also optimizes the performance of communication.
1. Two channels of Remoting
There are two main channels for Remoting: Tcp and Http. In .net, the IChannel interface is defined in System.Runtime.Remoting.Channel. The IChannel interface includes the TcpChannel channel type and the Http channel type. They correspond to these two types of Remoting channels.
The TcpChannel type is placed in the namespace System.Runtime.Remoting.Channel.Tcp. The Tcp channel provides a Socket-based transport tool that uses the Tcp protocol to transport serialized message flows across Remoting boundaries. The TcpChannel type serializes message objects in binary format by default, so it has higher transport performance. The HttpChannel type is placed in the namespace System.Runtime.Remoting.Channel.Http. It provides a way to use the Http protocol to transport serialized message flows over the Internet through a firewall. By default, the HttpChannel type serializes message objects using the Soap format, so it has better interoperability. Usually in the local area network, we use TcpChannel; more often. If we want to pass through the firewall, we use HttpChannel.
2. Activation of remote objects
Before accessing an object instance of a remote type, it must be created and initialized through a process called Activation. This client creates a remote object through a channel, which is called object activation. In Remoting, remote object activation is divided into two categories: server-side activation and client-side activation.
(1) Server-side activation, also known as WellKnow mode, many of which are translated into well-known objects. Why is it called well-known object activation mode? This is because the server application publishes this type on a well-known uniform Resource Identifier (URI) before activating the object instance. The server process then configures a WellKnown object for this type and publishes the object based on the specified port or address. .net Remoting divides server-side activation into SingleTon mode and SingleCall mode.
SingleTon mode: this is stateful mode. If set to SingleTon activation, Remoting establishes the same object instance for all clients. When an object is active, the SingleTon instance handles all subsequent client access requests, regardless of whether they are the same client or another client. The SingleTon instance will maintain its state throughout the method call. For example, if a remote object has an accumulation method (item0) that is called by multiple clients (for example, two). If set to SingleTon mode, the first customer gets a value of 1 and the second customer gets a value of 2 because they get the same object instance. If you are familiar with the state management of Asp.Net, we can think of it as an Application state.
SingleCall mode: SingleCall is a stateless mode. Once set to SingleCall mode, when the client calls the method of the remote object, Remoting establishes a remote object instance for each client, and the destruction of the object instance is automatically managed by GC. In the same example as the previous example, both customers accessing the remote object get 1. We can still learn from Asp.Net 's state management and think that it is a kind of Session state.
(2) client activation. Unlike the WellKnown mode, Remoting assigns a URI to each client-activated type when activating each object instance. Once the client activation mode receives a request from the client, an instance reference is established for each client. There is a difference between SingleCall mode and client activation mode: first, the object instance is created at a different time. The client activation method is instantiated once the client makes a request for the call, while the SingleCall is not created until the object method is called. Secondly, the object activated by SingleCall mode is stateless, the management of the object lifetime is managed by GC, while the client-activated object is stateful, and its life cycle can be customized. Third, the two activation modes are implemented differently on the server side and the client side. Especially on the client side, the SingleCall mode is activated by GetObject (), which calls the object's default constructor. Client-side activation mode, on the other hand, is activated by CreateInstance (), which can pass parameters, so you can call a custom constructor to create an instance.
Definition of remote object
As mentioned earlier, when the client gets the server-side object, it does not get the actual server-side object, but gets its reference. Therefore, in Remoting, there are some necessary definition specifications for remote objects to follow.
Because the objects passed by Remoting are referenced, the remote object classes passed must inherit MarshalByRefObject. MSDN's description of MarshalByRefObject is that MarshalByRefObject is the base class for objects that communicate across application domain boundaries by exchanging messages using agents. Objects that are not inherited from MarshalByRefObject are implicitly marshaled by value. When a remote application references an object marshaled by value, a copy of the object is passed across the remoting boundary. Because you want to communicate using the proxy method instead of the copy method, you need to inherit MarshallByRefObject.
The following is the 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 implements only the simplest method, which is to set up a person's basic information and return a Person class object. Notice the Person class returned here. Because the Person passed here is done by passing a value, and the Remoting requires that it be a referenced object, the Person class must be serialized.
Therefore, in a remote object in Remoting, if an object, such as a class, or structure, is also called or passed, the class or structure must be serialized
Attribute [SerializableAttribute]: [Serializable] public class Person {public Person () {} private string name; private string sex; private int age; public string Name {get {return name;} set {name = value;}} public string Sex {get {return sex;} set {sex = value;}} public int Age {get {return age;} set {age = value;}}
Compile the remote object into Dll as a class library. The Dll will be placed on the server side and the client side to add references.
The remote object that can be passed in Remoting can be of various types, including complex DataSet objects, as long as it can be serialized. Remote objects can also contain events, but the server-side handling of events is special, which I'll cover in part 3 of this series.
3. Server side
According to the first part, different server-side implementations of channel types vary according to the activation mode. In general, the server side should be divided into three steps:
1. Register the channel
To communicate across application domains, channels must be implemented. As mentioned earlier, Remoting provides an IChannel interface, which contains two types of channels, TcpChannel and HttpChannel, respectively. The two types are implemented in exactly the same way except for differences in performance and the format of serialized data, so let's take TcpChannel as an example.
To register TcpChannel, first add the reference "System.Runtime.Remoting" to the project, and then using the namespace: System.Runtime.Remoting.Channel.Tcp. The code is as follows:
TcpChannel channel = new TcpChannel (8080); ChannelServices.RegisterChannel (channel)
When the channel object is instantiated, the port number is passed as a parameter. Then call the static method RegisterChannel () to register the channel object.
2. Register remote objects
After registering a channel, to be able to activate a remote object, you must register the object in the channel. The method of registering an object varies depending on the activation mode.
(1) SingleTon mode
For WellKnown objects, you can do this through the static method RemotingConfiguration.RegisterWellKnownServiceType ():
RemotingConfiguration.RegisterWellKnownServiceType (typeof (ServerRemoteObject.ServerObject), "ServiceMessage", WellKnownObjectMode.SingleTon)
(2) SingleCall mode
The method of registering an object is basically the same as the SingleTon schema, just change the enumeration parameter WellKnownObjectMode to SingleCall.
RemotingConfiguration.RegisterWellKnownServiceType (typeof (ServerRemoteObject.ServerObject), "ServiceMessage", WellKnownObjectMode.SingleCall)
(3) client activation mode
For the client activation mode, the methods used are different, but there is little difference, and it is clear at a glance when you look at the code.
RemotingConfiguration.ApplicationName = "ServiceMessage"; RemotingConfiguration.RegisterActivatedServiceType (typeof (ServerRemoteObject.ServerObject))
Why set the ApplicationName property before registering the object method? In fact, this property is the URI of the object. For WellKnown mode, URI is placed in the parameters of the RegisterWellKnownServiceType () method, but you can also take it out to specifically assign a value to the ApplicationName attribute. In the overload of the RegisterActivatedServiceType () method, there is no argument to ApplicationName, so it must be separated.
3. Log out of the channel
If you want to shut down the service of Remoting, you need to log out of the channel, or you can turn off listening on the channel. In Remoting, when we register a channel, the listening of the channel is automatically turned on. If listening on the channel is turned off, the channel cannot accept requests from the client, but the channel still exists, and an exception will be thrown if you want to register the channel again.
/ / get the currently registered channel; IChannel [] channels = ChannelServices.RegisteredChannels;// close the specified channel named MyTcp; foreach (IChannel eachChannel in channels) {if (eachChannel.ChannelName = = "MyTcp") {TcpChannel tcpChannel = (TcpChannel) eachChannel; / / close snooping; tcpChannel.StopListening (null); / / logout channel; ChannelServices.UnregisterChannel (tcpChannel);}}
In the code, the RegisterdChannel attribute gets the currently registered channel. In Remoting, multiple channels are allowed to be registered at the same time, as will be explained later.
IV. Client
The client mainly does two things, one is to register the channel. As you can see from figure 1, both the server side and the client side of the Remoting must pass messages through the channel to obtain the remote object. The second step is to get the remote object.
1. Register the channel:
TcpChannel channel = new TcpChannel (); ChannelServices.RegisterChannel (channel)
Note that when the client instantiates the channel, it is the default constructor for the call, that is, no port number is passed. In fact, this port number is indispensable, except that its assignment is placed later as part of the Uri.
2. Get the remote object.
The same as the server side, different activation modes determine that the client will be implemented differently. However, this difference is only the difference between WellKnown activation mode and client activation mode, while for SingleTon and SingleCall mode, the client implementation is exactly the same.
(1) WellKnown activation mode
To get a well-known remote object on the server side, you can obtain it through the GetObject () method of the Activator process:
ServerRemoteObject.ServerObject serverObj = (ServerRemoteObject.ServerObject) Activator.GetObject (typeof (ServerRemoteObject.ServerObject), "tcp://localhost:8080/ServiceMessage")
First activated in WellKnown mode, the client gets the object by using GetObject (). The first parameter is the type of the remote object. The second parameter is the server-side uri. If it is a http channel, http://localhost:8080/ServiceMessage is naturally used. Because I am using a local machine, this is localhost, and you can replace it with a specific server IP address. The port must match the port on the server side. This is followed by the server-defined remote object service name, that is, the contents of the ApplicationName property.
(2) client activation mode
As mentioned earlier, the WellKnown pattern can only call the default constructor when creating an object on the client side, as the above code illustrates, because the GetObject () method cannot pass parameters to the constructor. Client activation mode, on the other hand, can create remote objects through custom constructors.
There are two ways to activate client mode:
1) call the static method RegisterActivatedClientType () of RemotingConfiguration. This method returns a value of Void, which simply registers the remote object with the client. Specific instantiation also requires calling 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 a class object of the type specified by the method parameter. Unlike the previous GetObject (), it invokes the constructor on the client side, while GetObject () just gets the object, while creating the instance is done on the server side. The CreateInstance () method has many overloads, and I'll highlight two of them that are commonly used.
A, public static object CreateInstance (Type type, object [] args, object [] activationAttributes)
Parameter description:
Type: the type of object to create.
Args: an array of parameters that match the number, order, and type of parameters to be called. If args is an empty array or null reference (Nothing in Visual Basic), the constructor with no arguments is called (the default constructor).
ActivationAttributes: an array of one or more attributes that can participate in activation.
The parameter args here is an object [] array type. It can pass parameters in the constructor of the object to be created. We can actually draw a conclusion from this: remote object classes passed in WellKnown activation mode can only use the default constructor, while Activated mode can be user-defined constructor. The activationAttributes parameter is usually used in this method to pass the server's url.
Suppose our remote object class ServerObject has a constructor:
ServerObject (string pName,string pSex,int pAge) {name = pName; sex = pSex; age = pAge;}
Then the code for the implementation is:
Object [] attrs = {new UrlAttribute ("tcp://localhost:8080/ServiceMessage")}; object [] objs = new object [3]; objs [0] = "wayfarer"; objs [1] = "male"; objs [2] = 28 objs ServerRemoteObject.ServerObject = Activator.CreateInstance (typeof (ServerRemoteObject.ServerObject), objs,attrs)
As you can see, the objs [] array passes the parameters of the constructor.
B, public static ObjectHandle CreateInstance (string assemblyName, string typeName, object [] activationAttribute)
Parameter description:
AssemblyName: the name of the assembly of type typeName will be found in it. If assemblyName is a null reference (Nothing in Visual Basic), search for the assembly that is executing.
TypeName: the name of the preferred type.
ActivationAttributes: an array of one or more attributes that can participate in activation.
The parameter description is clear at a glance. Notice that the return value of this method is of type ObjectHandle, so the code is different:
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 the default constructor that is called. The ObjectHandle.Unwrap () method returns the wrapped object.
Description: to use UrlAttribute, you also need to add: using System.Runtime.Remoting.Activation to the namespace
Fifth, the supplement of Remoting foundation.
Through the above description, we have basically completed the simplest Remoting program. This is a standard way to create Remoting programs, but in the actual development process, we may encounter all kinds of strange situations. If we only master one so-called "standard", it is impossible to imagine that we can "eat all the food in one move".
1. Register multiple channels
In Remoting, multiple channels are allowed to be created at the same time, that is, different channels are created according to different ports. However, Remoting requires that the name of the channel be different because it is used as the unique identifier of the channel. Although IChannel has a ChannelName property, this property is read-only. Therefore, the method of creating channels described earlier cannot achieve the requirement of registering multiple channels at the same time.
At this point, we must use the IDictionary interface in System.Collection:
Register the Tcp channel:
IDictionary tcpProp = new Hashtable (); tcpProp ["name"] = "tcp9090"; tcpProp ["port"] = 9090 witch iChannel channel = new TcpChannel (tcpProp, new BinaryClientFormatterSinkProvider (), new BinaryServerFormatterSinkProvider ()); ChannelServices.RegisterChannel (channel)
Register the Http channel:
IDictionary httpProp = new Hashtable (); httpProp ["name"] = "http8080"; httpProp ["port"] = 8080 httpProp iChannel channel = new HttpChannel (httpProp, new SoapClientFormatterSinkProvider (), new SoapServerFormatterSinkProvider ()); ChannelServices.RegisterChannel (channel)
In the name attribute, you can define a different channel name.
2. Remote object metadata dependency
Because remote objects are used by both the server and the client, the usual way is to generate two identical object Dll and add references respectively. However, for the sake of the security of the code and reducing the client's relevance to the remote object metadata, it is necessary to change this approach. That is, remote objects are implemented on the server side, and the metadata of these implementations is deleted on the client side.
Because of the different activation modes, there are different ways to create objects on the client side, so there are two cases to separate the dependencies of metadata.
(1) WellKnown activation mode:
It is realized through the interface. On the server side, the implementation of the interface and concrete class is provided, while only the interface is provided on the client side:
Public interface IServerObject {Person GetPersonInfo (string name,string sex,int age);} public class ServerObject:MarshalByRefObject,IServerObject {.}
Note: the name of the object assembly generated on both sides must be the same, strictly speaking, the name of the namespace must be the same.
(2) client activation mode:
As mentioned earlier, for client-side activation mode, whether you use the static method or the CreateInstance () method, you must call the constructor instantiation object on the client side. Therefore, the remote object we provide on the client side cannot provide only the interface without the implementation of the class. In fact, to achieve separation from remote object metadata, there are two ways to choose:
A. Use WellKnown activation mode to simulate client activation mode:
The approach is to take advantage of the "abstract factory" in the design pattern, and the following class diagram describes the overall solution:
We add abstract factory interfaces and implementation classes to the remote objects on the server side:
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 of the client:
Public interface IServerObject {Person GetPersonInfo (string name,string sex,int age);} public interface IServerObjFactory {IServerObject CreateInstance ();}
We register the remote object with WellKnown activation mode, on the server side:
/ / transfer object; RemotingConfiguration.RegisterWellKnownServiceType (typeof (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 client activation mode? From the point of view of the activation method, we use the SingleCall mode to activate the object, but what is activated at this time is not the remote object we want to pass, but the factory object. If the client wants to create a remote object, it should also be obtained through the CreateInstance () method of the factory object. This method is called on the client side. Therefore, it is implemented in the same way as client activation mode.
B. Replace the metadata of remote objects with alternative classes
In fact, we can deceive Remoting with a trick. The alternative class mentioned here is this trick. Since you are providing a service, the implementation details of the remote object passed by Remoting are of course placed on the server side. To put a copy of the object on the client is just a helpless move because the client has to call the constructor. Since the specific implementation is on the server side, and in order to be instantiated on the client side, it is better to implement this on the client side. As for the details of the implementation, don't worry about it.
If the remote object has a method, the server provides the method implementation, and the client provides the method OK. As for the implementation, you can throw an exception or return a null value; if the method returns void, then it can be empty. The key is that the client class object has this method. The implementation of this method is actually similar to the method declaration, so I say it is a trick. This is true of the method, and so is the constructor.
It is more intuitive to use code to illustrate this "conspiracy":
Server side:
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.NotImplementedException ();} public Person GetPersonInfo (string name,string sex,int age) {throw new System.NotImplementedException ();}}
Comparing the client side with the server side, the client-side method GetPersonInfo () has no specific implementation details, but just throws an exception. Or write the sentence return null directly, or OK it. We call this class on the client side an alternative class for remote objects.
3. Using configuration file to realize
In the method described earlier, the setting of the server uri, port, and activation mode is done in code. In fact, we can also use the configuration file to set. This has an advantage because the configuration file is an Xml document. If we need to change the port or something, we don't need to modify the program and recompile it, we just need to change the configuration file.
(1) configuration file on the server side:
If you are in client-activated mode, change wellknown to activated and remove the mode attribute.
Place the configuration file in the application folder of the server program and name it ServerRemoting.config. Then the previous server-side program can use this statement directly:
RemotingConfiguration.Configure ("ServerRemoting.config")
(2) client profile
If it is client-activated mode, modify it as above. The call also uses the RemotingConfiguration.Configure () method to invoke the configuration file stored on the client.
Configuration files can also be placed in machine.config. If the client program is a web application, it can be placed in web.config.
4. Start / close the specified remote object
No method like UnregisterWellKnownServiceType () is provided in Remoting, which means that once the remote object is registered, it will always exist in the channel if the channel is not closed. Whenever the client activates the object, an object instance is created. If only one remote object is transmitted by Remoting, there is no problem, just close the channel. What if multiple remote objects are transferred? What should I do to close the specified remote object? What if you need to start after shutting down?
We notice that the Marshal () and Disconnect () methods are provided in Remoting, and the answer is here. The Marshal () method converts a MarshalByRefObject class object into an ObjRef class object, which stores all the relevant information needed to generate a proxy to communicate with the remote object. This allows the instance to be serialized for transmission between application domains and over the network, and can be called by the client. The Disconnect () method disconnects the concrete instance object from the channel.
The methods are as follows:
First, register the 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 the object. Note that instead of RemotingConfiguration.RegisterWellKnownServiceType (), you use RemotingServices.Marshal ():
ObjRef objrefWellKnown = RemotingServices.Marshal (obj, "ServiceMessage")
If you want to log out of an object, then:
RemotingServices.Disconnect (obj)
Note that the class object of the Disconnect here must be the one instantiated earlier. Because of this, we can create specified remote objects as needed, and when closed, Disconnect previously instantiated objects.
As for the client-side invocation, which is the same as the previous WellKnown pattern, it is still obtained through Activator.GetObject (). However, from the point of view of the implementation code, we will notice a problem, because the server side explicitly instantiates the remote object, so no matter how many clients are the same or not, they all call the same remote object. So we call this method the simulated SingleTon mode.
Client activation mode
We can also simulate the client activation mode through Marshal () and Disconnect (). First of all, let's review the section "remote object metadata dependencies", in which I talk about using the "abstract factory" of design patterns to create object instances to simulate client activation patterns using SingleCall patterns. Think carefully about the SingleTon mode of the previous simulation. Is the answer about to come out?
In the "simulated SingleTon" mode, we Marshal a specific remote object instance so that the client can get the reference information for that object. So let's think differently, when we use an abstract factory to provide an interface, the factory class implements the method of creating a remote object. Then we create an instance of the factory class on the server side. Then Marshal the factory class instance. When the client gets the object, it does not get the specific remote object, but the specific factory class object. Then call the CreateInstance () method to create a specific remote object instance. At this point, for multiple clients, the same factory class object is called; however, the remote object is created on each client itself, so for the remote object, it is activated by the client and different objects are created.
When we want to start / close the specified object, we just need to use the Disconnet () method to log out the factory class object.
The above is all the content of the article "sample Analysis of Microsoft .net Remoting Foundation". Thank you for reading! I believe we all have a certain understanding, hope to share the content to help you, if you want to learn more knowledge, welcome to follow the industry information channel!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.