title: Handshaking with OPC Server
body: <p>I am using Interop.OPCAutomation.DLL (OPC DA Automation Wrapper 2.02) and connecting with a <a href="http://www.kepware.com/" rel="nofollow">Kepware server</a> which is configured to talk to some remote I/O. The client handles communication just fine when everything is working, but isn't smart enough to tell if the connection is lost (the machine's Ethernet cable has been unplugged, etc.)</p>
  
  <p>I am guessing that my only choice for getting Remote I/O status will be to subscribe to ConnectedGroup_DataChange and monitor OPC Item quality information, but is there a more simple way? Something like "<strong>-ping-</strong> hello remote I/O, are you still there?" </p>
  
  <p>Similarly, I need a way to check if the server is alive <em>or even exists</em> (<strong>-ping-</strong> are you there server?) As it stands,  I don't have any kind of handshaking and my client connects to the server with two simple lines:</p>
  
  <pre><code>ConnectedOPCServer = New OPCAutomation.OPCServer
  ConnectedOPCServer.Connect(OPCServerName, OPCNodeName)
  </code></pre>
  
  <p>I have created a function to return the server state but always seems to return 1, even after I've exited KEPServerEX. <strong>EDIT</strong>: I found out that exiting the program doesn't actually close the server. Using Process explorer from the sysinternals suite I found the server and suspended it. Doing so made my application hang on the .Connect line. Getting the server state is impossible until I'm actually connected, so <strong>how can I check if the server is there before trying to connect?</strong></p>
  
  <pre><code>Public Function GetServerState() As String
      Dim state As String = ConnectedOPCServer.ServerState.ToString
      Return state
  End Function
  </code></pre>
  
  <hr>
  
  <p><H1> Update </H1>
  Thought I would share the relevant piece of the final project.
  I ended up writing a new Interop.OPCAutomation dll wrapper class in C#.  </p>
  
  <p>Because of the COM object nature of the OPCAutomation dll, if anything goes wrong with the communication it throws exceptions. Thus, I've implemented exception catching for every function in the OPC communication class. I look for specific error messages and take action accordingly.<br>
  It beats crashing the application for something dumb that can be easily recovered from.<br>
  For ServerState, I don't even care what the message is so I don't catch the exception object.</p>
  
  <p>Here's my status function:</p>
  
  <pre class="lang-csh prettyprint-override"><code>public bool GetServerState()
  {
      try
      {
          int state = ConnectedOPCServer.ServerState;
          return true;
      }
      catch
      {
          // If server is unavailable, exception is thrown.
          CrossThreadLoggingEvent(
              Properties.Resources.MSG_Error_OPC08, optional_Lvl:3);
          return false; 
      }
  }
  </code></pre>
  
  <p>As you can see I don't bother to do anything with 'int state' because it will always return "1", or throw an exception.  </p>
  
  <p>Since I'm doing all OPC communication on a thread, I've implemented a thread-safe way to report logging events back to the main thread. </p>
  
  <p>That's it. Hope it helps someone.</p>