Step by step, Remoting, 1: Event

xiaoxiao2021-03-20  228

The concept does not say, please refer to MSDN related chapter:

Http://msdn.microsoft.com/library/chs/cpguide/html/cpconevents.asp Let's first transform the last program, add events for the last main thread method, can constantly trigger the event to report processing schedule:

public

Class

MyEventargs {

Private

int

_rate;

public

int

Rate {

get

{

Return

_rate;}}

public

MyEventargs

int

Rate) {

THIS

._Rate

=

Rate;}}

public

Class

MyObject {

public

Delegate

Void

MyEventHandler

Object

Sender, MyEventArgs E);

public

Event

Myeventhandler myevent;

public

Void

AlongTimeMethod

int

Time) {console.writeLine

"

Main thread method start

"

);

for

(

int

i

=

0

i

<

100

i

) {System.threading.thread.sleep (time); OnMyevent

New

Myeventargs (i));} console.writeline

"

Main thread method ends

"

}

protected

Void

ONMYEVENT (MyEventargs E) {

IF

(MyEvent)

! =

NULL

) {Myevent

THIS

, e);}}}}}

Then add a handler for an event:

Class

MyClient {[stathread]

Static

Void

Main

String

[] Args) {datetime dt

=

Datetime.now; myObject obj

=

New

MyObject (); obj.myevent

=

New

MyObject.myeventhandler (obj_myelent); obj.alongtimeMethod

50

Console.writeline

"

used

"

(Timespan) (DateTime.now)

-

DT)). Totalseconds

"

second

"

Console.readline ();

public

Static

Void

OBJ_MYEVENT

Object

Sender, myeventargs e) {console.writeLine

"

The main thread method is completed

"

E.rate

"

%

"

}}

Operating programs can be seen: Is this local, remote object event is also simple? In fact, there is no simplicity of imagination, because the object is in the distance, how can the server event client capture? It should be said that the event of the remote object can be divided into a client trigger - "Server Answer, Service Trigger -" Client Answers and Client Triggered - "Client Answer, the first is very simple, and two of the two need to have a middle Part. Below we have to add a progress mechanism to the schedule, first create our remote object: [SerializAble]

public

Class

Myeventargs: Eventargs {

Private

int

_rate;

Private

String

_ip;

public

int

Rate {

get

{

Return

_rate;}}

public

String

IP {

get

{

Return

_ip;}}

public

MyEventargs

int

Rate,

String

IP) {

THIS

._Rate

=

Rate;

THIS

._ip

=

IP;}}

public

Class

MyObject: MarshalByrefObject {

public

Delegate

Void

MyEventHandler

Object

Sender, MyEventArgs E);

public

Event

Myeventhandler myevent;

public

int

AlongTimeMethod

int

a,

int

b,

int

Time,

String

IP) {console.writeLine

"

Asynchronous method start

"

);

for

(

int

i

=

0

i

<

10

i

) {System.threading.thread.sleep (time); OnMyevent

New

MyEventArgs (i, IP));} console.writeline

"

End of asynchronous methods

"

);

Return

a

B;

protected

Void

ONMYEVENT (MyEventargs E) {

IF

(MyEvent)

! =

NULL

) {Myevent

THIS

, e);}}}}}

For the convenience of debugging, the server side and the client are implemented this time, the following is the server side:

Using

System;

Using

System.collections;

Using

System.Runtime.Remoting;

Using

System.Runtime.Remoting.Channels;

Using

System.Runtime.Remoting.Channels.tcp;

Using

System.Runtime.Serialization.formatters;

Namespace

RemoteServer {

Class

Myserver {[stathread]

Staticvoid

Main

String

[] Args) {remoteConfiguration.registerwellknownServiceType

Typeof

(RemoteObject.myObject),

"

RemoteObject.myObject

"

WellknownObjectMode.singleton; binaryserverformattersinkProvider ServerProvider

=

New

BinaryServerFormattersinkProvider (); binaryclientformattersinkProvider ClientProvider

=

New

BinaryClientFormattersinkProvider (); ServerProvider.TypefilterLevel

=

TypefilterLevel.Full; IDictionary Props

=

New

Hashtable (); prOPS [

"

port

"

]

=

9999

TCPCHANNEL CHANNEL

=

New

TcpChannel (Props, ClientProvider, ServerProvider); ChannelServices.registerChannel (CHANNEL); Console.Readline ();}}}

For the sake of simplicity, I will go to the previous test of the local event:

Using

System;

Using

System.net;

Using

System.collections;

Using

System.Text;

Using

System.Runtime.Remoting;

Using

System.Runtime.Remoting.Channels;

Using

System.Runtime.Remoting.Channels.tcp;

Using

System.Runtime.Serialization.formatters;

Class

Myclient {

Private

Delegate

int

MyDelegate

int

a,

int

b,

int

Time,

String

IP);

Private

Static

MyDelegate md; [stathread]

Static

Void

Main

String

[] Args) {datetime dt

=

DateTime.now; RemotingConfiguration.registerwellknownClientType

Typeof

(RemoteObject.myObject),

"

TCP: // localhost: 9999 / RemoteObject.myObject

"

Binary ServerFormattersinkProvider ServerProvider

=

New

BinaryServerFormattersinkProvider (); binaryclientformattersinkProvider ClientProvider

=

New

BinaryClientFormattersinkProvider (); serverProvider.TypefilterLevel =

TypefilterLevel.Full; IDictionary Props

=

New

Hashtable (); prOPS [

"

port

"

]

=

0

TCPCHANNEL CHANNEL

=

New

TcpChannel (Props, ClientProvider, ServerProvider); ChannelServices.registerChannel (Channel); RemoteObject.myObject APP

=

New

RemoteObject.myObject (); app.myevent

=

New

RemoteObject.myObject.myeventhandler (myEvent); MD

=

New

MyDelegate (app.alongtimeMethod); asyncCallback AC

=

New

AsyncCallback (MyClient.callback); iphostentry iphe

=

DNS.GETOSTBYNAME (DNS.GETHOSTNAME ()); IASYNCRESULT IAR

=

Md.BeginInvoke

1

,

2

,

300

, iphe.addresslist [

0

] .ToString (), AC,

NULL

); Method (); console.writeline

"

used

"

(Timespan) (DateTime.now)

-

DT)). Totalseconds

"

second

"

ChannelServices.unregisterChannel (CHANNEL); console.readline ();

public

Static

Void

Callback (IASYNCRESULT IAR) {

IF

(Iar.iscompleted) {console.writeLine

"

turn out

"

Md.Endinvoke (IAR);}}

public

Static

Void

Myevent

Object

Sender, RemoteObject.myeventargs e) {Console.WriteLine

"

From

"

E.IP

"

The asynchronous method is completed.

"

E.rate

*

10

"

%

"

}

public

Static

Void

Method () {console.writeline

"

Main thread method start

"

); System.threading.thread.sleep

5000

Console.writeline

"

Main thread method ends

"

}}

The code looks good, but Debug is started after the error: this is the problem I mentioned earlier, and the remote cannot have a local assembly, and the local event cannot be triggered. The solution is to add an event middleware to inherit MarshalByrefObject: Public

Class

EventClass: MarshalByrefObject {

public

Void

Myevent

Object

Sender, myeventargs e) {console.writeLine

"

From

"

E.IP

"

The asynchronous method is completed.

"

E.rate

*

10

"

%

"

}}

Then come to modify the client: put app.myevent = new remoteObject.myObject.myeventhandler (MyEvent);

RemoteObject.EventClass EC

=

New

RemoteObject.eventclass (); app.myevent

=

New

RemoteObject.myObject.myeventhandler (ec.myevent);

Delete the client's MyEvent static method. Run the program: The two windows before and after doing have the server and the client, which seems to have reached our request, in fact, the program has 2 vulnerabilities: 1. Open the new program after the client is closed, because the previous commission Chain loss, server program attempts to trigger event errors. 2, at the same time open several clients, the client receives all scheduled information, not just your own, broadcast nature news. (1) Close a client will affect other client events Reason: The client does not cancel the event subscription, it is closed, and the event subscriber can not find the event subscriber when the event is triggered: traverse the commission chain, find an exception, from the entrustment Removing (2) The server side is broadcast on the server side. The client can receive the event processing information for other clients: use the Singleton mode, share the remote object resolution: Because the remote object is status and does not share the instance, Client activation can select the modified server:

Using

System;

Using

System.collections;

Using

System.Runtime.Remoting;

Using

System.Runtime.Remoting.Channels;

Using

System.Runtime.Remoting.Channels.tcp;

Using

System.Runtime.Serialization.formatters;

Namespace

RemoteServer {

Class

Myserver {[stathread]

Static

Void

Main

String

[] Args) {remoteConfiguration.ApplicationName

=

"

RemoteObject.myObject

"

RemotingConfiguration.RegisterActiVatedServiceType

Typeof

(RemoteObject.myObject); binaryserverformattersinkProvider ServerProvider =

New

BinaryServerFormattersinkProvider (); binaryclientformattersinkProvider ClientProvider

=

New

BinaryClientFormattersinkProvider (); ServerProvider.TypefilterLevel

=

TypefilterLevel.Full; IDictionary Props

=

New

Hashtable (); prOPS [

"

port

"

]

=

8888

TCPCHANNEL CHANNEL

=

New

TcpChannel (Props, ClientProvider, ServerProvider); ChannelServices.registerChannel (CHANNEL); Console.Readline ();}}}

Modified remote object:

Using

System;

Namespace

RemoteObject {[serializable]

public

Class

Myeventargs: Eventargs {

Private

int

_rate;

Private

String

_ip;

public

int

Rate {

get

{

Return

_rate;}}

public

String

IP {

get

{

Return

_ip;}}

public

MyEventargs

int

Rate,

String

IP) {

THIS

._Rate

=

Rate;

THIS

._ip

=

IP;}}

public

Class

MyObject: MarshalByrefObject {

public

Delegate

Void

MyEventHandler

Object

Sender, MyEventArgs E);

public

Event

Myeventhandler myevent;

public

String

TMP;

public

int

AlongTimeMethod

int

a,

int

b,

int

Time,

String

IP) {console.writeLine

"

From

"

IP

"

Asynchronous method begins

"

);

for

(

int

i

=

1

i

<=

10

i

) {System.threading.thread.sleep (time); console.writeline

"

From

"

IP

"

The asynchronous method is completed.

"

i

*

10

"

%

"

OnmyEvent

New

MyEventArgs (i, IP));} console.writeline

"

From

"

IP

"

End of asynchronous methods

"

);

Return

a

B;

protected

Void

ONMYEVENT (MyEventargs E) {

IF

(MyEvent)

! =

NULL

) {

Foreach

(Delegate D

in

MyEvent.getinvocationList ()) {

Try

{((MyEventHandler) D)

THIS

, e);

Catch

{MyEvent

- =

MyeventHandler D;}}}}}}

public

Class

EventClass: MarshalByrefObject {

public

Void

Myevent

Object

Sender, myeventargs e) {

IF

((MyObject) Sender) .tmp

==

E.IP) Console.WriteLine

"

The asynchronous method is completed.

"

E.rate

*

10

"

%

"

}}}

Modified client:

Using

System;

Using

System.net;

Using

System.collections;

Using

System.Text;

Using

System.Runtime.Remoting;

Using

System.Runtime.Remoting.Channels;

Using

System.Runtime.Remoting.Channels.tcp;

Using

System.Runtime.Serialization.formatters;

Class

Myclient {

Private

Delegate

int

MyDelegate

int

a,

int

b,

int

Time,

String

IP);

Private

Static

MyDelegate MD;

Static

RemoteObject.myObject app;

Static

RemoteObject.EventClass EC;

Static

DateTime dt; [stathread]

Static

Void

Main

String

[] Args) {dt

=

DateTime.now; RemotingConfiguration.registerActiVatedClientType

Typeof

(RemoteObject.myObject),

"

TCP: // localhost: 8888 / RemoteObject.myObject

"

Binary ServerFormattersinkProvider ServerProvider

=

New

BinaryServerFormattersinkProvider (); binaryclientformattersinkProvider ClientProvider =

New

BinaryClientFormattersinkProvider (); ServerProvider.TypefilterLevel

=

TypefilterLevel.Full; IDictionary Props

=

New

Hashtable (); prOPS [

"

port

"

]

=

0

TCPCHANNEL CHANNEL

=

New

TCPChannel (Props, ClientProvider, ServerProvider); ChannelServices.RegisterChannel (CHANNEL); APP

=

New

RemoteObject.myObject (); EC

=

New

RemoteObject.eventclass (); app.myevent

=

New

RemoteObject.myObject.myeventhandler (ec.myevent); MD

=

New

MyDelegate (app.alongtimeMethod); asyncCallback AC

=

New

AsyncCallback (MyClient.callback); iphostentry iphe

=

DNS.GETHOSTBYNAME (DNS.GETHOSTNAME ()); Random Rnd

=

New

Random (system.environment.tickcount);

String

IP

=

Iphe.addresslist [

0

] .ToString ()

"

(

"

RND.NEXT

100000000

) .Tostring ()

"

)

"

App.TMP

=

IP; IASYNCRESULT IAR

=

Md.BeginInvoke

1

,

2

,

500

, IP, AC,

NULL

); Method (); console.writeline

"

used

"

(Timespan) (DateTime.now)

-

DT)). Totalseconds

"

second

"

ChannelServices.unregisterChannel (CHANNEL); console.readline ();

public

Static

Void

Callback (IASYNCRESULT IAR) {

IF

(Iar.iscompleted) {console.writeLine

"

turn out

"

Md.Endinvoke (IAR); app.myevent

- =

New

RemoteObject.myObject.myeventhandler (ec.myevent);}}

public

Static

Void

Method () {console.writeline

"Main thread method start

"

); System.threading.thread.sleep

5000

Console.writeline

"

Main thread method ends

"

}}

It is necessary to keep up with the random number behind the IP address because you may open multiple clients on a machine, you need to distinguish multiple clients at this time. Note: All of my examples are deployed remote objects on the client and server side. In fact, this practice is not very good, we should only deploy the interface in both places, and the remote object is only deployed on the server.

转载请注明原文地址:https://www.9cbs.com/read-130419.html

New Post(0)