Re: Intermittent Remoting Event Callback Problem

From: Sam Santiago (ssantiago_at_n0spam-SoftiTechture.com)
Date: 07/31/04


Date: Sat, 31 Jul 2004 11:35:54 -0700

Here's another question. You have configured your OPCEngine object as
SingleCall:

<wellknown mode="SingleCall" type="Sequoia.Manufacturing.OPCEngine,
OPCServer" objectUri="OPCEngine" />

And based on this statement you appear to want a Singleton OPCServer object:

 m_oOPCServer = m_oOPCEngine.getInstance(m_sStationID);

What type of object are you expecting m_oOPCServer to be? Did you want it
to be an SAO? A Singleton or Singlecall? If so, this will not work. Any
MarshalByRefObj created using the New statement and returned to the client
by a call to a remote object, in this case the m_oOPCEngine.getInstance
method, is treated as a CAO. Is this what you wanted?

Thanks,

Sam

-- 
_______________________________
Sam Santiago
ssantiago@n0spam-SoftiTechture.com
http://www.SoftiTechture.com
_______________________________
"Mike Hacker" <MikeHacker@discussions.microsoft.com> wrote in message
news:47F119E2-B162-4B0D-9669-17432F1FB724@microsoft.com...
> Hello,
>
> 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
>
>                    --> Connects to Server
>
>                    <-- Server Factory generates object
>
>                    --> Proxy registers callback to server ping delegate
>
>                    --> 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
>
>               <-- Server invokes client_ping delegate
>
> .. If proxy receives a response, the loop starts again.
>
>
>
> 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>
>
>             <customErrors mode="off" />
>
>             <application name="Sequoia">
>
>                   <service>
>
>                         <wellknown mode="SingleCall"
type="Sequoia.Manufacturing.OPCEngine, OPCServer" objectUri="OPCEngine" />
>
>                   </service>
>
>
>
>                   <channels>
>
>                         <channel ref="tcp" name="IO Server" port="1999"
useIpAddress="true">
>
>                               <clientProviders>
>
>                                     <formatter ref="binary" />
>
>                               </clientProviders>
>
>                               <serverProviders>
>
>                                     <formatter ref="binary"
typeFilterLevel="Full" />
>
>                               </serverProviders>
>
>                         </channel>
>
>                   </channels>
>
>             </application>
>
>       </system.runtime.remoting>
>
>
>
> Here's the code I'm using on the client to create the channel:
>
>
>
>                         System.Collections.IDictionary properties = new
System.Collections.Hashtable();
>
>                         properties["name"] = "OPCProxyClient::" +
m_sStationID + "::"
>
>                               + System.Guid.NewGuid().ToString();
>
>                         properties["port"] = 0;
>
>                         properties["useIpAddress"] = true;
>
>
>
>                         BinaryServerFormatterSinkProvider serverProvider
>
>                               = new BinaryServerFormatterSinkProvider();
>
>
>
>                         BinaryClientFormatterSinkProvider clientProvider
>
>                               = new BinaryClientFormatterSinkProvider();
>
>
>
>                         serverProvider.TypeFilterLevel =
System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;
>
>
>
>                         oChan = new TcpChannel(properties, clientProvider,
serverProvider);
>
>                         ChannelServices.RegisterChannel(oChan);
>
>
>
> // Casting to the class factory
>
> // interface, and having it generate a new OPCServer object
>
> // for us
>
>                         Sequoia.Manufacturing.iOPCEngine m_oOPCEngine =
(iOPCEngine)
>
>
System.Runtime.Remoting.RemotingServices.Connect(typeof(iOPCServer)
>
>                               , m_sServerURL + "/Sequoia/OPCEngine");
>
>
>
>                         m_oOPCServer =
m_oOPCEngine.getInstance(m_sStationID);
>
>
>
> // This line instructs the SAO to start // it's work
>
>                         bool bStartResult=m_oOPCServer.Start();
>
>
Sequoia.Manufacturing.Util.WriteLogMessage("OPCProxy -- OPCServer Start
Result: " + bStartResult
>
>                               + " Station: " + m_sStationID,1,false);
>
>
>
>                         m_oOPCServer.OnPLCDataChange  += new
DataChangeHandler(m_oOPCServer_OnPLCDataChange);
>
>                         m_oOPCServer.OnServerShutdown += new
OPCServerShutdown(m_oOPCServer_OnServerShutdown);
>
> // Here's my ping callback registration
>
> m_oOPCServer.OnPingCallback   += new
OPCServerEvent(m_oOPCServer_OnPingCallback);
>
>
>
> 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!
>
>


Relevant Pages

  • Re: Custom COM callbacks
    ... a COM server cleanup connections to a client if the client crashes". ... I have an out of process COM server that provides notifications of events to ... clients via a custom callback interface. ... call Release on the callback interfaces, ...
    (microsoft.public.vc.atl)
  • Re: Intermittent Remoting Event Callback Problem
    ... OPCEngine published component that was originally a singleton. ... requested by the client through a single-call class factory. ... to reconnect to the server and re-register the callbacks when an error ... the callback *STILL* fails. ...
    (microsoft.public.dotnet.distributed_apps)
  • RE: Controls not updated by callback event
    ... In a client callback, a client script function sends a request to the ... Another function receives the result from the server code ... Microsoft Online Community Support ...
    (microsoft.public.dotnet.framework.aspnet.buildingcontrols)
  • Re: Non-blocking notification mechanism via RMI
    ... The remote software would provide the callback object to the server. ... If you are saying that you don't want to use a remote callback mechanism then there really isn't much you can do but block. ... Another approach is to have the server post answers to a client specific queue and have the client periodically remotely dequeue answers. ...
    (comp.lang.java.programmer)
  • Re: What doesnt lend itself to OO?
    ... >> proxy and instructs the server to constuct the real object. ... rather than client code. ... If 'clock' is instantiated in the server, ... > for the server interface at the OOA level. ...
    (comp.object)