Windows Vista Forums
Vista Forums Home Join Vista Forums Windows 7 Forum Vista Tutorials Tags
Welcome to Windows Vista Forums. Our forum is dedicated to helping you find solutions with any problems, errors or issues you are experiencing with Windows Vista. The Vista forum also covers news and updates and has an extensive Windows Vista tutorial section that covers a wide range of tips and tricks.

Go Back   Vista Forums > Misc Newsgroups > .NET General

Vista - How Can a Server Raise an Event at a Client (Remoting)

Reply
 
Old 07-28-2008   #1 (permalink)
Charles Law


 
 

How Can a Server Raise an Event at a Client (Remoting)

I've read numerous articles and bits of code that purport to do this, but I
think there is a gap somewhere (quite possibly in my head).

I have a server, which is actually a Windows service. I also have a client
that needs to retrieve information from this service, but also needs to
receive events from it, when it (the client) is running. I've done all the
MBO stuff, and the client can pick up info from the server at will. That was
the easy bit.

Now, I want the service/server to be able to raise an event, and the client
to handle it. The sticking point seems to be: How do I raise the event in
the server? It seems to me that in order to do that I need a reference to
the MBO on which the event is to be raised. In my server I have

Dim identifier As String = "MyServer"
Dim mode As WellKnownObjectMode = WellKnownObjectMode.Singleton
Dim entry As WellKnownServiceTypeEntry
entry = New WellKnownServiceTypeEntry(GetType(MyServerMBO), identifier,
mode)
RemotingConfiguration.RegisterWellKnownServiceType(entry)

But how do I get a reference to the MyServerMBO that is created?

I have tried making everything Shared, so that I don't need a reference, but
although I can see the RaiseEvent call being made, the debugger steps right
over it, indicating that there is nothing attached to it, and the client
never receives a call.

Have I missed something here?

TIA

Charles



My System SpecsSystem Spec
Old 07-28-2008   #2 (permalink)
Norman Yuan


 
 

Re: How Can a Server Raise an Event at a Client (Remoting)

You may want to look into CallBack in WCF (why still Remoting when WCF gives
you a better tool to use?).

"Charles Law" <blank@xxxxxx> wrote in message
news:epZT5uM8IHA.3696@xxxxxx
Quote:

> I've read numerous articles and bits of code that purport to do this, but
> I think there is a gap somewhere (quite possibly in my head).
>
> I have a server, which is actually a Windows service. I also have a client
> that needs to retrieve information from this service, but also needs to
> receive events from it, when it (the client) is running. I've done all the
> MBO stuff, and the client can pick up info from the server at will. That
> was the easy bit.
>
> Now, I want the service/server to be able to raise an event, and the
> client to handle it. The sticking point seems to be: How do I raise the
> event in the server? It seems to me that in order to do that I need a
> reference to the MBO on which the event is to be raised. In my server I
> have
>
> Dim identifier As String = "MyServer"
> Dim mode As WellKnownObjectMode = WellKnownObjectMode.Singleton
> Dim entry As WellKnownServiceTypeEntry
> entry = New WellKnownServiceTypeEntry(GetType(MyServerMBO), identifier,
> mode)
> RemotingConfiguration.RegisterWellKnownServiceType(entry)
>
> But how do I get a reference to the MyServerMBO that is created?
>
> I have tried making everything Shared, so that I don't need a reference,
> but although I can see the RaiseEvent call being made, the debugger steps
> right over it, indicating that there is nothing attached to it, and the
> client never receives a call.
>
> Have I missed something here?
>
> TIA
>
> Charles
>
>
My System SpecsSystem Spec
Old 07-28-2008   #3 (permalink)
Charles Law


 
 

Re: How Can a Server Raise an Event at a Client (Remoting)

Hi Norman

Thanks for the very quick response. The main reason for not going WCF (yet)
is the learning curve. That said, if it solves the problem where my current
approach is taking time to get right, perhaps I would be better spending a
few hours looking at WCF now. Just knowing that it can do it for me might be
the incentive I need.

Charles


"Norman Yuan" <FakeName@xxxxxx> wrote in message
news:OwS4N3M8IHA.616@xxxxxx
Quote:

> You may want to look into CallBack in WCF (why still Remoting when WCF
> gives you a better tool to use?).
>
> "Charles Law" <blank@xxxxxx> wrote in message
> news:epZT5uM8IHA.3696@xxxxxx
Quote:

>> I've read numerous articles and bits of code that purport to do this, but
>> I think there is a gap somewhere (quite possibly in my head).
>>
>> I have a server, which is actually a Windows service. I also have a
>> client that needs to retrieve information from this service, but also
>> needs to receive events from it, when it (the client) is running. I've
>> done all the MBO stuff, and the client can pick up info from the server
>> at will. That was the easy bit.
>>
>> Now, I want the service/server to be able to raise an event, and the
>> client to handle it. The sticking point seems to be: How do I raise the
>> event in the server? It seems to me that in order to do that I need a
>> reference to the MBO on which the event is to be raised. In my server I
>> have
>>
>> Dim identifier As String = "MyServer"
>> Dim mode As WellKnownObjectMode = WellKnownObjectMode.Singleton
>> Dim entry As WellKnownServiceTypeEntry
>> entry = New WellKnownServiceTypeEntry(GetType(MyServerMBO), identifier,
>> mode)
>> RemotingConfiguration.RegisterWellKnownServiceType(entry)
>>
>> But how do I get a reference to the MyServerMBO that is created?
>>
>> I have tried making everything Shared, so that I don't need a reference,
>> but although I can see the RaiseEvent call being made, the debugger steps
>> right over it, indicating that there is nothing attached to it, and the
>> client never receives a call.
>>
>> Have I missed something here?
>>
>> TIA
>>
>> Charles
>>
>>
>

My System SpecsSystem Spec
Old 07-28-2008   #4 (permalink)
sloan


 
 

Re: How Can a Server Raise an Event at a Client (Remoting)


Here is a clean cut WCF sample:
http://sholliday.spaces.live.com/Blo...842A!158.entry

I would invest in the learning curve on this one.

As much as I liked/used remoting on occasion, the newer model is simpler and
more powerful.

...



"Charles Law" <blank@xxxxxx> wrote in message
news:Omr2B8M8IHA.1468@xxxxxx
Quote:

> Hi Norman
>
> Thanks for the very quick response. The main reason for not going WCF
> (yet) is the learning curve. That said, if it solves the problem where my
> current approach is taking time to get right, perhaps I would be better
> spending a few hours looking at WCF now. Just knowing that it can do it
> for me might be the incentive I need.
>
> Charles
>
>
> "Norman Yuan" <FakeName@xxxxxx> wrote in message
> news:OwS4N3M8IHA.616@xxxxxx
Quote:

>> You may want to look into CallBack in WCF (why still Remoting when WCF
>> gives you a better tool to use?).
>>
>> "Charles Law" <blank@xxxxxx> wrote in message
>> news:epZT5uM8IHA.3696@xxxxxx
Quote:

>>> I've read numerous articles and bits of code that purport to do this,
>>> but I think there is a gap somewhere (quite possibly in my head).
>>>
>>> I have a server, which is actually a Windows service. I also have a
>>> client that needs to retrieve information from this service, but also
>>> needs to receive events from it, when it (the client) is running. I've
>>> done all the MBO stuff, and the client can pick up info from the server
>>> at will. That was the easy bit.
>>>
>>> Now, I want the service/server to be able to raise an event, and the
>>> client to handle it. The sticking point seems to be: How do I raise the
>>> event in the server? It seems to me that in order to do that I need a
>>> reference to the MBO on which the event is to be raised. In my server I
>>> have
>>>
>>> Dim identifier As String = "MyServer"
>>> Dim mode As WellKnownObjectMode = WellKnownObjectMode.Singleton
>>> Dim entry As WellKnownServiceTypeEntry
>>> entry = New WellKnownServiceTypeEntry(GetType(MyServerMBO), identifier,
>>> mode)
>>> RemotingConfiguration.RegisterWellKnownServiceType(entry)
>>>
>>> But how do I get a reference to the MyServerMBO that is created?
>>>
>>> I have tried making everything Shared, so that I don't need a reference,
>>> but although I can see the RaiseEvent call being made, the debugger
>>> steps right over it, indicating that there is nothing attached to it,
>>> and the client never receives a call.
>>>
>>> Have I missed something here?
>>>
>>> TIA
>>>
>>> Charles
>>>
>>>
>>
>
>

My System SpecsSystem Spec
Old 07-28-2008   #5 (permalink)
Charles Law


 
 

Re: How Can a Server Raise an Event at a Client (Remoting)

Thanks for the link. I'll certainly take a look.

Charles


"sloan" <sloan@xxxxxx> wrote in message
news:ucRr6tN8IHA.1568@xxxxxx
Quote:

>
> Here is a clean cut WCF sample:
> http://sholliday.spaces.live.com/Blo...842A!158.entry
>
> I would invest in the learning curve on this one.
>
> As much as I liked/used remoting on occasion, the newer model is simpler
> and more powerful.
>
> ..
>
>
>
> "Charles Law" <blank@xxxxxx> wrote in message
> news:Omr2B8M8IHA.1468@xxxxxx
Quote:

>> Hi Norman
>>
>> Thanks for the very quick response. The main reason for not going WCF
>> (yet) is the learning curve. That said, if it solves the problem where my
>> current approach is taking time to get right, perhaps I would be better
>> spending a few hours looking at WCF now. Just knowing that it can do it
>> for me might be the incentive I need.
>>
>> Charles
>>
>>
>> "Norman Yuan" <FakeName@xxxxxx> wrote in message
>> news:OwS4N3M8IHA.616@xxxxxx
Quote:

>>> You may want to look into CallBack in WCF (why still Remoting when WCF
>>> gives you a better tool to use?).
>>>
>>> "Charles Law" <blank@xxxxxx> wrote in message
>>> news:epZT5uM8IHA.3696@xxxxxx
>>>> I've read numerous articles and bits of code that purport to do this,
>>>> but I think there is a gap somewhere (quite possibly in my head).
>>>>
>>>> I have a server, which is actually a Windows service. I also have a
>>>> client that needs to retrieve information from this service, but also
>>>> needs to receive events from it, when it (the client) is running. I've
>>>> done all the MBO stuff, and the client can pick up info from the server
>>>> at will. That was the easy bit.
>>>>
>>>> Now, I want the service/server to be able to raise an event, and the
>>>> client to handle it. The sticking point seems to be: How do I raise the
>>>> event in the server? It seems to me that in order to do that I need a
>>>> reference to the MBO on which the event is to be raised. In my server I
>>>> have
>>>>
>>>> Dim identifier As String = "MyServer"
>>>> Dim mode As WellKnownObjectMode = WellKnownObjectMode.Singleton
>>>> Dim entry As WellKnownServiceTypeEntry
>>>> entry = New WellKnownServiceTypeEntry(GetType(MyServerMBO), identifier,
>>>> mode)
>>>> RemotingConfiguration.RegisterWellKnownServiceType(entry)
>>>>
>>>> But how do I get a reference to the MyServerMBO that is created?
>>>>
>>>> I have tried making everything Shared, so that I don't need a
>>>> reference, but although I can see the RaiseEvent call being made, the
>>>> debugger steps right over it, indicating that there is nothing attached
>>>> to it, and the client never receives a call.
>>>>
>>>> Have I missed something here?
>>>>
>>>> TIA
>>>>
>>>> Charles
>>>>
>>>>
>>>
>>
>>
>
>

My System SpecsSystem Spec
Old 07-28-2008   #6 (permalink)
Nicholas Paldino [.NET/C# MVP]


 
 

Re: How Can a Server Raise an Event at a Client (Remoting)

Charles,

I would recommend against using an event in this situation. Rather,
have a shared interface which represents the callback from the server to the
client, and then implement an instance of that object on the client side,
making sure the class derives from MarshalByRefObject. Then, expose a
method on the service which takes an instance of this implementation and
pass your MarshalByRefObject to that method on the service.

This allows the service to call back into the client. Then, you can
have that object raise events which other classes can respond to. I don't
recommend calling back directly to say, the UI, because the calls will come
in on threads other than the UI thread.

--
- Nicholas Paldino [.NET/C# MVP]
- mvp@xxxxxx

"Charles Law" <blank@xxxxxx> wrote in message
news:epZT5uM8IHA.3696@xxxxxx
Quote:

> I've read numerous articles and bits of code that purport to do this, but
> I think there is a gap somewhere (quite possibly in my head).
>
> I have a server, which is actually a Windows service. I also have a client
> that needs to retrieve information from this service, but also needs to
> receive events from it, when it (the client) is running. I've done all the
> MBO stuff, and the client can pick up info from the server at will. That
> was the easy bit.
>
> Now, I want the service/server to be able to raise an event, and the
> client to handle it. The sticking point seems to be: How do I raise the
> event in the server? It seems to me that in order to do that I need a
> reference to the MBO on which the event is to be raised. In my server I
> have
>
> Dim identifier As String = "MyServer"
> Dim mode As WellKnownObjectMode = WellKnownObjectMode.Singleton
> Dim entry As WellKnownServiceTypeEntry
> entry = New WellKnownServiceTypeEntry(GetType(MyServerMBO), identifier,
> mode)
> RemotingConfiguration.RegisterWellKnownServiceType(entry)
>
> But how do I get a reference to the MyServerMBO that is created?
>
> I have tried making everything Shared, so that I don't need a reference,
> but although I can see the RaiseEvent call being made, the debugger steps
> right over it, indicating that there is nothing attached to it, and the
> client never receives a call.
>
> Have I missed something here?
>
> TIA
>
> Charles
>
>

My System SpecsSystem Spec
Old 07-28-2008   #7 (permalink)
Charles Law


 
 

Re: How Can a Server Raise an Event at a Client (Remoting)

Hi Nicholas

Thanks for the reply. I think I have half done what you suggest already. I
have a class in the server that inherits from MarshalByRefObject. I create
an instance of that in the client, and then use it to sink events raised by
the server. By passing this object to the server on which to raise its
events, it seems that the server and client would be quite tightly bound
together though. If the client goes away without telling the server
(crashes), the server would try to raise events on an object that doesn't
exist, but where the reference is not nothing. Then what would happen?

I'm not sure that solution gets over the UI thread issue either. The event
will always be on the wrong thread until it is marshalled to the right
thread, or BeginInvoke is used. I think I would have to do that in any case.

Charles


"Nicholas Paldino [.NET/C# MVP]" <mvp@xxxxxx> wrote in
message news:upF73RO8IHA.3724@xxxxxx
Quote:

> Charles,
>
> I would recommend against using an event in this situation. Rather,
> have a shared interface which represents the callback from the server to
> the client, and then implement an instance of that object on the client
> side, making sure the class derives from MarshalByRefObject. Then, expose
> a method on the service which takes an instance of this implementation and
> pass your MarshalByRefObject to that method on the service.
>
> This allows the service to call back into the client. Then, you can
> have that object raise events which other classes can respond to. I don't
> recommend calling back directly to say, the UI, because the calls will
> come in on threads other than the UI thread.
>
> --
> - Nicholas Paldino [.NET/C# MVP]
> - mvp@xxxxxx
>
> "Charles Law" <blank@xxxxxx> wrote in message
> news:epZT5uM8IHA.3696@xxxxxx
Quote:

>> I've read numerous articles and bits of code that purport to do this, but
>> I think there is a gap somewhere (quite possibly in my head).
>>
>> I have a server, which is actually a Windows service. I also have a
>> client that needs to retrieve information from this service, but also
>> needs to receive events from it, when it (the client) is running. I've
>> done all the MBO stuff, and the client can pick up info from the server
>> at will. That was the easy bit.
>>
>> Now, I want the service/server to be able to raise an event, and the
>> client to handle it. The sticking point seems to be: How do I raise the
>> event in the server? It seems to me that in order to do that I need a
>> reference to the MBO on which the event is to be raised. In my server I
>> have
>>
>> Dim identifier As String = "MyServer"
>> Dim mode As WellKnownObjectMode = WellKnownObjectMode.Singleton
>> Dim entry As WellKnownServiceTypeEntry
>> entry = New WellKnownServiceTypeEntry(GetType(MyServerMBO), identifier,
>> mode)
>> RemotingConfiguration.RegisterWellKnownServiceType(entry)
>>
>> But how do I get a reference to the MyServerMBO that is created?
>>
>> I have tried making everything Shared, so that I don't need a reference,
>> but although I can see the RaiseEvent call being made, the debugger steps
>> right over it, indicating that there is nothing attached to it, and the
>> client never receives a call.
>>
>> Have I missed something here?
>>
>> TIA
>>
>> Charles
>>
>>
>
>

My System SpecsSystem Spec
Old 07-28-2008   #8 (permalink)
Nicholas Paldino [.NET/C# MVP]


 
 

Re: How Can a Server Raise an Event at a Client (Remoting)

Charles,

There is no solution that is going to get over the message coming in on
a non-UI thread. It just complicates things when the implementation of the
callback interface on the client is on the UI object itself. You are better
off having a separate object on the client that derives from MBRO and then
exposes events that other objects can respond to. Any calls from the server
to the client which result in updating the UI will have to be marshaled from
the callback to the UI thread.

Regarding the server and the client being tightly bound, this is no more
the case than when you use events. Yes, the server has a reference to the
client, but with events, the same thing occurs.

If the client goes away (in this case, the object implementing the
callback interface, or the server, for that matter, since they both derive
from MBRO), then the lease will expire, and the proxy on the other end will
be invalidated.


--
- Nicholas Paldino [.NET/C# MVP]
- mvp@xxxxxx


"Charles Law" <blank@xxxxxx> wrote in message
news:OZwmNEP8IHA.3624@xxxxxx
Quote:

> Hi Nicholas
>
> Thanks for the reply. I think I have half done what you suggest already. I
> have a class in the server that inherits from MarshalByRefObject. I create
> an instance of that in the client, and then use it to sink events raised
> by the server. By passing this object to the server on which to raise its
> events, it seems that the server and client would be quite tightly bound
> together though. If the client goes away without telling the server
> (crashes), the server would try to raise events on an object that doesn't
> exist, but where the reference is not nothing. Then what would happen?
>
> I'm not sure that solution gets over the UI thread issue either. The event
> will always be on the wrong thread until it is marshalled to the right
> thread, or BeginInvoke is used. I think I would have to do that in any
> case.
>
> Charles
>
>
> "Nicholas Paldino [.NET/C# MVP]" <mvp@xxxxxx> wrote
> in message news:upF73RO8IHA.3724@xxxxxx
Quote:

>> Charles,
>>
>> I would recommend against using an event in this situation. Rather,
>> have a shared interface which represents the callback from the server to
>> the client, and then implement an instance of that object on the client
>> side, making sure the class derives from MarshalByRefObject. Then,
>> expose a method on the service which takes an instance of this
>> implementation and pass your MarshalByRefObject to that method on the
>> service.
>>
>> This allows the service to call back into the client. Then, you can
>> have that object raise events which other classes can respond to. I
>> don't recommend calling back directly to say, the UI, because the calls
>> will come in on threads other than the UI thread.
>>
>> --
>> - Nicholas Paldino [.NET/C# MVP]
>> - mvp@xxxxxx
>>
>> "Charles Law" <blank@xxxxxx> wrote in message
>> news:epZT5uM8IHA.3696@xxxxxx
Quote:

>>> I've read numerous articles and bits of code that purport to do this,
>>> but I think there is a gap somewhere (quite possibly in my head).
>>>
>>> I have a server, which is actually a Windows service. I also have a
>>> client that needs to retrieve information from this service, but also
>>> needs to receive events from it, when it (the client) is running. I've
>>> done all the MBO stuff, and the client can pick up info from the server
>>> at will. That was the easy bit.
>>>
>>> Now, I want the service/server to be able to raise an event, and the
>>> client to handle it. The sticking point seems to be: How do I raise the
>>> event in the server? It seems to me that in order to do that I need a
>>> reference to the MBO on which the event is to be raised. In my server I
>>> have
>>>
>>> Dim identifier As String = "MyServer"
>>> Dim mode As WellKnownObjectMode = WellKnownObjectMode.Singleton
>>> Dim entry As WellKnownServiceTypeEntry
>>> entry = New WellKnownServiceTypeEntry(GetType(MyServerMBO), identifier,
>>> mode)
>>> RemotingConfiguration.RegisterWellKnownServiceType(entry)
>>>
>>> But how do I get a reference to the MyServerMBO that is created?
>>>
>>> I have tried making everything Shared, so that I don't need a reference,
>>> but although I can see the RaiseEvent call being made, the debugger
>>> steps right over it, indicating that there is nothing attached to it,
>>> and the client never receives a call.
>>>
>>> Have I missed something here?
>>>
>>> TIA
>>>
>>> Charles
>>>
>>>
>>
>>
>
>

My System SpecsSystem Spec
Old 07-28-2008   #9 (permalink)
Charles Law


 
 

Re: How Can a Server Raise an Event at a Client (Remoting)

Is there a way to determine if the lease has expired, and does it expire
immediately? A test I just did suggests that it doesn't. I killed my client
and allowed the server to attempt to raise another event. I got an exception
to the effect that the "machine had actively refused the connection". Is
there a neater way than just trap the exception when it occurs? Obviously,
in normal operation the client would tell the server that it was going away,
but what if it doesn't?

In my case, there will be quite regular communication between server and
client (when one is running), but to be on the safe side I override
InitializeLifetimeService. Would that cause a problem?

I think I can see a way to make this work for me, using your suggestion, but
bits of it just seem a little inelegant. For example, if this were a
listener then it would need to attach to another process and listen without
the other process being aware, and detach without upsetting the main
process. It would also not impact the main process performance because it
would listen asynchronously. I think of it like a recital. It doesn't affect
the performer whether there are one, ten or none listening. The recital
continues the same. That's really all I am trying to do here.

Regards

Charles


"Nicholas Paldino [.NET/C# MVP]" <mvp@xxxxxx> wrote in
message news:u4U2rQP8IHA.3260@xxxxxx
Quote:

> Charles,
>
> There is no solution that is going to get over the message coming in on
> a non-UI thread. It just complicates things when the implementation of
> the callback interface on the client is on the UI object itself. You are
> better off having a separate object on the client that derives from MBRO
> and then exposes events that other objects can respond to. Any calls from
> the server to the client which result in updating the UI will have to be
> marshaled from the callback to the UI thread.
>
> Regarding the server and the client being tightly bound, this is no
> more the case than when you use events. Yes, the server has a reference
> to the client, but with events, the same thing occurs.
>
> If the client goes away (in this case, the object implementing the
> callback interface, or the server, for that matter, since they both derive
> from MBRO), then the lease will expire, and the proxy on the other end
> will be invalidated.
>
>
> --
> - Nicholas Paldino [.NET/C# MVP]
> - mvp@xxxxxx
>
>
> "Charles Law" <blank@xxxxxx> wrote in message
> news:OZwmNEP8IHA.3624@xxxxxx
Quote:

>> Hi Nicholas
>>
>> Thanks for the reply. I think I have half done what you suggest already.
>> I have a class in the server that inherits from MarshalByRefObject. I
>> create an instance of that in the client, and then use it to sink events
>> raised by the server. By passing this object to the server on which to
>> raise its events, it seems that the server and client would be quite
>> tightly bound together though. If the client goes away without telling
>> the server (crashes), the server would try to raise events on an object
>> that doesn't exist, but where the reference is not nothing. Then what
>> would happen?
>>
>> I'm not sure that solution gets over the UI thread issue either. The
>> event will always be on the wrong thread until it is marshalled to the
>> right thread, or BeginInvoke is used. I think I would have to do that in
>> any case.
>>
>> Charles
>>
>>
>> "Nicholas Paldino [.NET/C# MVP]" <mvp@xxxxxx> wrote
>> in message news:upF73RO8IHA.3724@xxxxxx
Quote:

>>> Charles,
>>>
>>> I would recommend against using an event in this situation. Rather,
>>> have a shared interface which represents the callback from the server to
>>> the client, and then implement an instance of that object on the client
>>> side, making sure the class derives from MarshalByRefObject. Then,
>>> expose a method on the service which takes an instance of this
>>> implementation and pass your MarshalByRefObject to that method on the
>>> service.
>>>
>>> This allows the service to call back into the client. Then, you can
>>> have that object raise events which other classes can respond to. I
>>> don't recommend calling back directly to say, the UI, because the calls
>>> will come in on threads other than the UI thread.
>>>
>>> --
>>> - Nicholas Paldino [.NET/C# MVP]
>>> - mvp@xxxxxx
>>>
>>> "Charles Law" <blank@xxxxxx> wrote in message
>>> news:epZT5uM8IHA.3696@xxxxxx
>>>> I've read numerous articles and bits of code that purport to do this,
>>>> but I think there is a gap somewhere (quite possibly in my head).
>>>>
>>>> I have a server, which is actually a Windows service. I also have a
>>>> client that needs to retrieve information from this service, but also
>>>> needs to receive events from it, when it (the client) is running. I've
>>>> done all the MBO stuff, and the client can pick up info from the server
>>>> at will. That was the easy bit.
>>>>
>>>> Now, I want the service/server to be able to raise an event, and the
>>>> client to handle it. The sticking point seems to be: How do I raise the
>>>> event in the server? It seems to me that in order to do that I need a
>>>> reference to the MBO on which the event is to be raised. In my server I
>>>> have
>>>>
>>>> Dim identifier As String = "MyServer"
>>>> Dim mode As WellKnownObjectMode = WellKnownObjectMode.Singleton
>>>> Dim entry As WellKnownServiceTypeEntry
>>>> entry = New WellKnownServiceTypeEntry(GetType(MyServerMBO), identifier,
>>>> mode)
>>>> RemotingConfiguration.RegisterWellKnownServiceType(entry)
>>>>
>>>> But how do I get a reference to the MyServerMBO that is created?
>>>>
>>>> I have tried making everything Shared, so that I don't need a
>>>> reference, but although I can see the RaiseEvent call being made, the
>>>> debugger steps right over it, indicating that there is nothing attached
>>>> to it, and the client never receives a call.
>>>>
>>>> Have I missed something here?
>>>>
>>>> TIA
>>>>
>>>> Charles
>>>>
>>>>
>>>
>>>
>>
>>
>
>

My System SpecsSystem Spec
Old 07-28-2008   #10 (permalink)
Nicholas Paldino [.NET/C# MVP]


 
 

Re: How Can a Server Raise an Event at a Client (Remoting)

Charles,

You can try and get the ILease implementation of the other side. You
just have to call the static GetLifetimeService method on the
RemotingServices class, passing the service proxy to it, and casting the
return value to ILease.

You should then be able to check the CurrentState property of the ILease
implementation to get the state of the lease.

I can't see why overriding InitializeLifetimeService would cause a
problem, but then again, I don't know what you are doing in it, so I can't
say for sure.

I can undersand what you are trying to do, but under the covers, using
events or callbacks over remoting, the fact of the matter is that the server
has to be aware of the client in some manner in order to fire the event or
perform the callback. The eventing just doesn't work as nicely as a
callback interface, as there are a lot of hoops to jump through.


--
- Nicholas Paldino [.NET/C# MVP]
- mvp@xxxxxx

"Charles Law" <blank@xxxxxx> wrote in message
news:%23f482cP8IHA.3724@xxxxxx
Quote:

> Is there a way to determine if the lease has expired, and does it expire
> immediately? A test I just did suggests that it doesn't. I killed my
> client and allowed the server to attempt to raise another event. I got an
> exception to the effect that the "machine had actively refused the
> connection". Is there a neater way than just trap the exception when it
> occurs? Obviously, in normal operation the client would tell the server
> that it was going away, but what if it doesn't?
>
> In my case, there will be quite regular communication between server and
> client (when one is running), but to be on the safe side I override
> InitializeLifetimeService. Would that cause a problem?
>
> I think I can see a way to make this work for me, using your suggestion,
> but bits of it just seem a little inelegant. For example, if this were a
> listener then it would need to attach to another process and listen
> without the other process being aware, and detach without upsetting the
> main process. It would also not impact the main process performance
> because it would listen asynchronously. I think of it like a recital. It
> doesn't affect the performer whether there are one, ten or none listening.
> The recital continues the same. That's really all I am trying to do here.
>
> Regards
>
> Charles
>
>
> "Nicholas Paldino [.NET/C# MVP]" <mvp@xxxxxx> wrote
> in message news:u4U2rQP8IHA.3260@xxxxxx
Quote:

>> Charles,
>>
>> There is no solution that is going to get over the message coming in
>> on a non-UI thread. It just complicates things when the implementation
>> of the callback interface on the client is on the UI object itself. You
>> are better off having a separate object on the client that derives from
>> MBRO and then exposes events that other objects can respond to. Any
>> calls from the server to the client which result in updating the UI will
>> have to be marshaled from the callback to the UI thread.
>>
>> Regarding the server and the client being tightly bound, this is no
>> more the case than when you use events. Yes, the server has a reference
>> to the client, but with events, the same thing occurs.
>>
>> If the client goes away (in this case, the object implementing the
>> callback interface, or the server, for that matter, since they both
>> derive from MBRO), then the lease will expire, and the proxy on the other
>> end will be invalidated.
>>
>>
>> --
>> - Nicholas Paldino [.NET/C# MVP]
>> - mvp@xxxxxx
>>
>>
>> "Charles Law" <blank@xxxxxx> wrote in message
>> news:OZwmNEP8IHA.3624@xxxxxx
Quote:

>>> Hi Nicholas
>>>
>>> Thanks for the reply. I think I have half done what you suggest already.
>>> I have a class in the server that inherits from MarshalByRefObject. I
>>> create an instance of that in the client, and then use it to sink events
>>> raised by the server. By passing this object to the server on which to
>>> raise its events, it seems that the server and client would be quite
>>> tightly bound together though. If the client goes away without telling
>>> the server (crashes), the server would try to raise events on an object
>>> that doesn't exist, but where the reference is not nothing. Then what
>>> would happen?
>>>
>>> I'm not sure that solution gets over the UI thread issue either. The
>>> event will always be on the wrong thread until it is marshalled to the
>>> right thread, or BeginInvoke is used. I think I would have to do that in
>>> any case.
>>>
>>> Charles
>>>
>>>
>>> "Nicholas Paldino [.NET/C# MVP]" <mvp@xxxxxx> wrote
>>> in message news:upF73RO8IHA.3724@xxxxxx
>>>> Charles,
>>>>
>>>> I would recommend against using an event in this situation. Rather,
>>>> have a shared interface which represents the callback from the server
>>>> to the client, and then implement an instance of that object on the
>>>> client side, making sure the class derives from MarshalByRefObject.
>>>> Then, expose a method on the service which takes an instance of this
>>>> implementation and pass your MarshalByRefObject to that method on the
>>>> service.
>>>>
>>>> This allows the service to call back into the client. Then, you can
>>>> have that object raise events which other classes can respond to. I
>>>> don't recommend calling back directly to say, the UI, because the calls
>>>> will come in on threads other than the UI thread.
>>>>
>>>> --
>>>> - Nicholas Paldino [.NET/C# MVP]
>>>> - mvp@xxxxxx
>>>>
>>>> "Charles Law" <blank@xxxxxx> wrote in message
>>>> news:epZT5uM8IHA.3696@xxxxxx
>>>>> I've read numerous articles and bits of code that purport to do this,
>>>>> but I think there is a gap somewhere (quite possibly in my head).
>>>>>
>>>>> I have a server, which is actually a Windows service. I also have a
>>>>> client that needs to retrieve information from this service, but also
>>>>> needs to receive events from it, when it (the client) is running. I've
>>>>> done all the MBO stuff, and the client can pick up info from the
>>>>> server at will. That was the easy bit.
>>>>>
>>>>> Now, I want the service/server to be able to raise an event, and the
>>>>> client to handle it. The sticking point seems to be: How do I raise
>>>>> the event in the server? It seems to me that in order to do that I
>>>>> need a reference to the MBO on which the event is to be raised. In my
>>>>> server I have
>>>>>
>>>>> Dim identifier As String = "MyServer"
>>>>> Dim mode As WellKnownObjectMode = WellKnownObjectMode.Singleton
>>>>> Dim entry As WellKnownServiceTypeEntry
>>>>> entry = New WellKnownServiceTypeEntry(GetType(MyServerMBO),
>>>>> identifier, mode)
>>>>> RemotingConfiguration.RegisterWellKnownServiceType(entry)
>>>>>
>>>>> But how do I get a reference to the MyServerMBO that is created?
>>>>>
>>>>> I have tried making everything Shared, so that I don't need a
>>>>> reference, but although I can see the RaiseEvent call being made, the
>>>>> debugger steps right over it, indicating that there is nothing
>>>>> attached to it, and the client never receives a call.
>>>>>
>>>>> Have I missed something here?
>>>>>
>>>>> TIA
>>>>>
>>>>> Charles
>>>>>
>>>>>
>>>>
>>>>
>>>
>>>
>>
>>
>
>

My System SpecsSystem Spec
Reply

Thread Tools


Similar Threads
Thread Forum
PowerShell Remoting from Win7 RC to Server 08 R2 beta PowerShell
CTP2: Please do not abandon Windows XP and Server 2003 for remoting/psjobs at final release PowerShell
Re: .Net Remoting Server .NET General


Vista Forums is an independent web site and has not been authorized,
sponsored, or otherwise approved by Microsoft Corporation.
"Windows Vista", the Start Orb, and related materials are trademarks of Microsoft Corp.
© Designer Media Ltd

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 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46