I am aware of the leasing plumbing within the framework, however, in this instance, I need to know within 2-5 seconds if the “server” I’m talking to has gone down. (Not simply by the object suddenly going out of scope…etc.) It’s used in a production/manufacturing scenario, and the solution requires the client to pro-actively be aware of this particular service it’s talking to. If it goes “down” (IE – reboot, network cable disconnect, etc) Then some additional “work” needs to occur to bring things back online automatically. In most cases, the SAO should be in use “forever”. I was not trying to use this ping method as a means of keeping the object alive. I have overridden the initializelifetimeservices method of the marshalbyref interface where appropriate. Everything works most of the time, but I get the exception posted yesterday occasionally after binding all my callbacks – in fact, it’s not just the ping callback – as you can see from the code, there are 2 more delegates. If either of those are invoked when this unusual circumstance arises, than they produce the exact same exception….albeit a slightly different callstack.
> I think you are trying to circumvent to whole reason leases were created. You might want to read this link:
>
[quoted text clipped - 221 lines]
> >
> > One interesting thing, both in our client’s installation, and in our “sterile” office environment, we’re not using DNS – and are (from our understanding of the channel objects) taking advantage of the useIPAddress – could this intermittent behavior be caused by the “server” object not being able to “see” the client to make the callback? Any assistance would be appreciated!
You might want to consider load balancing or some type of fail over with
your SAOs vs. trying to determine if they are still alive continuously.
Check out this link as a start:
INFO: Configurations That Microsoft Supports for Microsoft .NET Remoting
with Network Load Balancing
http://support.microsoft.com/default.aspx?scid=kb;en-us;830217
Good luck.
Thanks,
Sam

Signature
_______________________________
Sam Santiago
ssantiago@n0spam-SoftiTechture.com
http://www.SoftiTechture.com
_______________________________
> I am aware of the leasing plumbing within the framework, however, in this
instance, I need to know within 2-5 seconds if the "server" I'm talking to
has gone down. (Not simply by the object suddenly going out of scope.etc.)
It's used in a production/manufacturing scenario, and the solution requires
the client to pro-actively be aware of this particular service it's talking
to. If it goes "down" (IE - reboot, network cable disconnect, etc) Then
some additional "work" needs to occur to bring things back online
automatically. In most cases, the SAO should be in use "forever". I was
not trying to use this ping method as a means of keeping the object alive.
I have overridden the initializelifetimeservices method of the marshalbyref
interface where appropriate. Everything works most of the time, but I get
the exception posted yesterday occasionally after binding all my callbacks -
in fact, it's not just the ping callback - as you can see from the code,
there are 2 more delegates. If either of those are invoked when this
unusual circumstance arises, than they produce the exact same
exception..albeit a slightly different callstack.
> > I think you are trying to circumvent to whole reason leases were created. You might want to read this link:
> >
> > Improving .NET Application Performance and Scalability
http://msdn.microsoft.com/library/en-us/dnpag/html/scalenetchapt11.asp?frame=tru
e#scalenetchapt11_topic10
> > Here's an excerpt:
> > ..NET Remoting Leases
> > To reduce network communication, .NET applications no longer use a ping-based approach for distributed garbage collection. Instead, .NET
remoting uses a lease-based system to determine the lifetime of a
distributed object.
> > When an object is created, a lease is established that determines the life of the object. The default lifetime for a remote object is five
minutes. If the object is not used for a five-minute period, the lease
manager releases the object, which makes it available for garbage
collection. When an object is called within the five-minute threshold, the
following "renewal on call" process occurs:
> > a.. When the call is made, the lifetime of the lease is checked.
> > b.. If the lifetime of the lease is longer than two minutes, nothing is done.
[quoted text clipped - 6 lines]
> > >
> > > I have been experiencing occasional problems when calling a delegate
from a SAO resulting in a callback to a "proxy"/wrapper class. Upon
startup, the "client" (understandably running as a server when a callback
occurs) is successfully (in all cases - even when the issue occurs) able to
connect and make calls to methods on the SAO. After connecting, the
"client" creates a worker thread that periodically makes a call to a "ping"
method on the SAO; which in turn invokes a callback to the client.a sort of
2-way heartbeat that was needed to permit the "client" the ability to
monitor and reconnect to the server upon disconnection. Here's a diagram:
> > > Client --> Creates Proxy object to interact with SAO
> > >
[quoted text clipped - 5 lines]
> > >
> > > --> Proxy generates monitor thread to periodically
"ping" the server
> > > .dwell (loop begin)
> > >
> > > --> Proxy calls ping method on server - proxy dwells for
a
> > > Response from the server
> > >
[quoted text clipped - 3 lines]
> > >
> > > Here's the problem: Occasionally -- On startup (after the channel is
programmatically registered), everything is successful, and the client
invokes the SAO's ping method, but when the server attempts to invoke the
proxy's callback method, it fails with the following exception:
> > > [07/29/2004 09:39:23:9985 AM] Severity: 0 - OPCServer::FireDataChangeEvent-->Client Unreachable...Details:
System.Net.Sockets.SocketException: No connection could be made because the
target machine actively refused it
> > > Server stack trace:
> > >
> > > at System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
> > >
> > > at
System.Runtime.Remoting.Channels.RemoteConnection.CreateNewSocket()
> > > at System.Runtime.Remoting.Channels.SocketCache.GetSocket(String machineAndPort)
> > >
> > > at
System.Runtime.Remoting.Channels.Tcp.TcpClientTransportSink.SendRequestWithR
etry(IMessage msg, ITransportHeaders requestHeaders, Stream requestStream)
> > > at
System.Runtime.Remoting.Channels.Tcp.TcpClientTransportSink.AsyncProcessRequ
est(IClientChannelSinkStack sinkStack, IMessage msg, ITransportHeaders
headers, Stream stream)
> > > at
System.Runtime.Remoting.Channels.BinaryClientFormatterSink.AsyncProcessMessa
ge(IMessage msg, IMessageSink replySink)
> > > Exception rethrown at [0]:
> > >
> > > at
System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage
reqMsg, IMessage retMsg)
> > > at
System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&
msgData, Int32 type)
> > > at Sequoia.Manufacturing.DataChangeHandler.EndInvoke(IAsyncResult result)
> > >
> > > at Sequoia.Manufacturing.OPCServer.CallbackComplete(IAsyncResult ar)
> > >
> > > at
System.Runtime.Remoting.Messaging.AsyncResult.SyncProcessMessage(IMessage
msg)
> > > at
System.Runtime.Remoting.Messaging.AsyncReplySink.SyncProcessMessage(IMessage
reqMsg)
> > > at
System.Runtime.Remoting.Channels.BinaryClientFormatterSink.AsyncProcessMessa
ge(IMessage msg, IMessageSink replySink)
> > > at
System.Runtime.Remoting.Messaging.ClientContextTerminatorSink.AsyncProcessMe
ssage(IMessage reqMsg, IMessageSink replySink)
> > > at
System.Runtime.Remoting.Messaging.EnvoyTerminatorSink.AsyncProcessMessage(IM
essage reqMsg, IMessageSink replySink)
> > > at
System.Runtime.Remoting.Proxies.RemotingProxy.InternalInvokeAsync(IMessageSi
nk ar, Message reqMsg, Boolean useDispatchMessage, Int32 callType)
> > > at
System.Runtime.Remoting.Proxies.RemotingProxy.InternalInvoke(IMethodCallMess
age reqMcmMsg, Boolean useDispatchMessage, Int32 callType)
> > > at System.Runtime.Remoting.Proxies.RemotingProxy.Invoke(IMessage reqMsg)
> > >
> > > at
System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&
msgData, Int32 type)
> > > at
Sequoia.Manufacturing.DataChangeHandler.BeginInvoke(tPlcDataResult PlcData,
AsyncCallback callback, Object object)
> > > at
Sequoia.Manufacturing.OPCServer.FireDataChangeEvent(tPlcDataResult
DataChangeResult)
> > > I'm using the .config file on the Server component (service) with the
class factory generating the SAO's, and programmatically registering the
channel on the "client" (as I need to be able to tear down the channel and
re-create it when an error occurs - something that can't be done if you use
Remoting.configure.) Here's what the "servers" config file looks like:
> > > <system.runtime.remoting>
> > >
[quoted text clipped - 21 lines]
> > >
> > > <formatter ref="binary"
typeFilterLevel="Full" />
> > > </serverProviders>
> > >
[quoted text clipped - 25 lines]
> > >
> > > = new
BinaryClientFormatterSinkProvider();
> > > serverProvider.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;
> > >
[quoted text clipped - 9 lines]
> > >
> > > Sequoia.Manufacturing.iOPCEngine m_oOPCEngine = (iOPCEngine)
System.Runtime.Remoting.RemotingServices.Connect(typeof(iOPCServer)
> > > , m_sServerURL + "/Sequoia/OPCEngine");
> > >
[quoted text clipped - 3 lines]
> > >
> > > bool bStartResult=m_oOPCServer.Start();
Sequoia.Manufacturing.Util.WriteLogMessage("OPCProxy -- OPCServer Start
Result: " + bStartResult
> > > + " Station: " + m_sStationID,1,false);
> > >
[quoted text clipped - 7 lines]
> > >
> > > One interesting thing, both in our client's installation, and in our
"sterile" office environment, we're not using DNS - and are (from our
understanding of the channel objects) taking advantage of the useIPAddress -
could this intermittent behavior be caused by the "server" object not being
able to "see" the client to make the callback? Any assistance would be
appreciated!