Event processing in .NET Remoting
Many people have doubts about the events in Remoting. Now the process of fully implementing the event processing in Remoting is written out, and summarizes the mistakes that are easy to make, I hope to give you some help. Now there is a message board program: In the following code, MsGboard is a shared message board instance that survives the server-side in Singleton mode. AddMessage is the interface of the client to add a message, and the msgboard is as follows:
public
Class
Msgboard: MarshalByrefObject
{Public delegate void EventDelegate (string info); public evenet de - de-{console.writeline (info);
IF (onInfoadded! = NULL)
Onfoadded (Info);}
When there is a client to add a message, an event is stimulated, and our client subscribes to the event to get a notification of the message board update. The server-side code is as follows:
USING DIRECTIVES
#region Using directivesusing System; using System.Collections.Generic; using System.Text; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Http; using System.Runtime. Serialization.formatters; / ** ////// # endRegion
Namespace
ConsOLESERVER
{Class Program {static void Main (string [] args) {RemotingConfiguration.RegisterWellKnownServiceType (typeof (MyLibrary.MsgBoard), "MyUri", WellKnownObjectMode.Singleton); HttpChannel myChannel = new HttpChannel (1080); ChannelServices.RegisterChannel (myChannel); / ** /// IServerChannelSink sc = myChannel.ChannelSinkChain; while (! sc = null) {if (sc is BinaryServerFormatterSink) {((BinaryServerFormatterSink) sc) .TypeFilterLevel = TypeFilterLevel.Full; // break;} if (sc is SoapServerFormatterSink) {((SoapServerFormatterSink) sc) .TypeFilterLevel = TypeFilterLevel.Full; // break;} sc = sc.NextChannelSink;} Console.WriteLine ( "Server Started"); Console.ReadLine ();}}} we can not detailed To care about the server-side program, we only need to know: 1. The server registers the type of remote service. Ie formattersink.typefilterLevel = typefilterlevel.low). In order to achieve remote event processing, we must release the constraint to make serverformattersink.typefilterlevel = typefilterlevel.full
We need to care about our client code:
USING DIRECTIVES
#region Using directivesusing System; using System.Collections.Generic; using System.Text; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Http; using System.Runtime. Serialization.formatters; #endregion
Namespace
Consoleclient
{Class Program {static void Main (string [] args) {try {RemotingConfiguration.RegisterWellKnownClientType (typeof (MyLibrary.MsgBoard), "Http: // localhost: 1080 / MyUri"); HttpChannel myChannel = new HttpChannel (1000); ChannelServices .RegisterChannel (myChannel); IServerChannelSink sc = myChannel.ChannelSinkChain; Console.WriteLine ( "Client Started"); MyLibrary.MsgBoard msgbd = new MyLibrary.MsgBoard (); /**////msgbd.OnInfoAdded = new MyLibrary. MsgBoard.EventDelegate (msgbd_OnInfoAdded); MyLibrary.eventClass evclass = new MyLibrary.eventClass (); msgbd.OnInfoAdded = new MyLibrary.MsgBoard.EventDelegate (evclass.msgbd_OnInfoAdded); / ** //// instead msgbd.AddMessage ( "Hello All "); console.readline ();} catch (exception eXC) {console.writeline (Exc.s TackTrace); console.readline ();}} public static void msgbd_oninfoadded (String info) {Console.Writeline ("Info On Server Event: {0}", Info);}}} Please note: This is here to use an instance Methods to subscribe to the event of the server component, the instance type is defined as follows:
public
Class
EventClass: MarshalByrefObject
{Public void msgbd_oninfoadded (string info) {Console.WriteLine ("Info from Server Event: {0}", info);}}
Why do you want to do this? .NET Framework requires that the publisher of the event must have metadata of the event subscriber, and the simple method of providing metadata is to add a reference to the client program, but in fact, we don't need this, we will subscribe The declaration of the program is concentrated on the remote class, and the metadata of the assembly is originally a server and client. At this time, we must notice that the class of the subscription event is also declared into MarshalByrefObject, which is a restriction in the .NET Framework 2.0, delegated in the serialization information contains the address of the corresponding instance of the function, when the server is returned, You can address the object instance of the client to the client and perform the corresponding member method. Since it can be addressed by the server, the subscription object requires MarshalByrefObject, which is not difficult to understand. Prior to .NET Framework 2.0, we can use an event containing a delegation to subscribe to the server component, but after 2.0, if you use a static member to subscribe, the response will be executed in the server space, so we have to remember Remote processing always handles some form of instance members, and static members cannot. Summary: To implement remote processing remote processing, remember the following principles: 1. DelegationSerializationHolder is not allowed to be reverse sequence 2, the event initiator must have a subscriber's metadata 3, remote processing always processed Instance members, and this example must be MarshalByreference:
Since HTTPChannel uses ChannelSinkChain as an open attribute, we can directly modify TypeFilterLevel, and team TCPChannel, ChannelSinkchain is unable to access directly, we can see SinkProvider in the monitor window, we can only go to intervene in constructing TcPChannel and Tcpchannel The method of the configuration file can be used, but the code helps to understand. The following is an example of TypeFilterLevel HttpChannel Review: BinaryServerFormatterSinkProvider serverProv = new BinaryServerFormatterSinkProvider (); serverProv.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full; BinaryClientFormatterSinkProvider clientProv = new BinaryClientFormatterSinkProvider (); IDictionary props = new Hashtable (); props [ "port"] = 1080; // HttpChannel chan = new HttpChannel (props, clientProv, provider); // ChannelServices.RegisterChannel (chan); RemotingConfiguration.RegisterWellKnownServiceType (typeof (MyLibrary.MsgBoard), "MyUri", WellKnownObjectMode.Singleton) TCPCHANNEL MyChannel = New Tcpchannel (Props, ClientProv, ServerProv); ChannelServices.RegisterChannel (MyChannel);
Tuesday, November 09, 2004 12:05 Amhref = "http://blog.joycode.com/joe/services/pingback.aspx" Rel = "pingback" />