We zijn er weer eens met een vraag... Ik heb zopas een client/server applicatie geschreven met sockets maar zou nu wel eens met Remoting willen experimenteren omdat dat voor bepaalde toepassingen veel interessanter is dan sockets en de hele rompslomp die daarbij komt kijken. Dankzij enkele uitstekende tutorials op codeproject duurde het natuurlijk niet lang eer ik Remoting aan de praat kreeg. Zolang ik het bij losse functies hield was er geen probleem, maar toen ik een volledige class wou remoten stootte ik op een lastig probleem. Waarschijnlijk 'by design', maar ik had toch graag geweten waarom het zo is en hoe ik het kan omzeilen.
Even een heel simpel voorbeeldje om het probleem te schetsen:
Volgende class in de serverapplicatie wordt het object dat ik via Remoting beschikbaar wil maken voor de clientapplicatie:
Wat gaat er nu mis in de clientapplicatie (vereenvoudigde code)?
Kan iemand me uitleggen waarom dit zo is, en hoe ik dit kan verhelpen? Ik zou graag de class volledig gebruiken in m'n client applicatie, maar bepaalde waarden moeten door de serverapplicatie ingevuld worden. Dat laatste is nu al mogelijk, maar ik kan de class gewoon niet deftig werkende krijgen in de clientapplicatie door bovenstaand probleem...
Even een heel simpel voorbeeldje om het probleem te schetsen:
Volgende class in de serverapplicatie wordt het object dat ik via Remoting beschikbaar wil maken voor de clientapplicatie:
C#:
De gebruikte interface voor de clientapplicatie is:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| public class Object : MarshalByRefObject,MyInterface { // Variabelen private bool bTest = false; // Constructor public Object() { } // Destructor ~Object() { } // Lees bTest public bool Lees() { return bTest; } // Zet bTest public void Zet(bool b) { bTest = b; } } |
C#:
De werking is vrij straight-forward. Met functie Lees() lees ik de huidige waarde van boolean bTest uit en met Zet() kan ik de waarde ervan wijzigen. De serverapplicatie start het remotingproces met volgende code:1
2
3
4
5
| public interface MyInterface { bool Lees(); void Zet(bool b) } |
C#:
1
2
3
4
5
6
7
| // SERVER TcpChannel tcpChannel = new TcpChannel(4848); ChannelServices.RegisterChannel(tcpChannel); RemotingConfiguration.RegisterWellKnownServiceType( Type.GetType("Object"), "RemoteObject", WellKnownObjectMode.SingleCall); |
Wat gaat er nu mis in de clientapplicatie (vereenvoudigde code)?
C#:
Ik had verwacht dat die laatste regel 'true' zou teruggeven. Maar blijkbaar kan de geremote class zijn member variabelen niet veranderen. Binnen een functie geen enkel probleem, maar erbuiten wil het niet werken.1
2
3
4
5
6
7
8
9
10
| // CLIENT TcpChannel tcpChannel = new TcpChannel(); ChannelServices.RegisterChannel(tcpChannel); MyInterface myRemoteObject = (MyInterface)Activator.GetObject(typeof(MyInterface), "tcp://192.168.1.10:4848/RemoteObject"); .. myRemoteObject.Lees(); // Geeft false terug myRemoteObject.Zet(true); myRemoteObject.Lees(); // Geeft false terug!!! |
Kan iemand me uitleggen waarom dit zo is, en hoe ik dit kan verhelpen? Ik zou graag de class volledig gebruiken in m'n client applicatie, maar bepaalde waarden moeten door de serverapplicatie ingevuld worden. Dat laatste is nu al mogelijk, maar ik kan de class gewoon niet deftig werkende krijgen in de clientapplicatie door bovenstaand probleem...
[ Voor 18% gewijzigd door mahi op 13-09-2005 12:00 ]
A bus station is where a bus stops. A train station is where a train stops... On my desk I have a workstation.