Interop.OPCAutomation.DLL (OPC DA Automation Wrapper 2.02) を使用し、リモート I/O と通信するように構成されたKepware サーバーに接続しています。すべてが機能している場合、クライアントは通信を正常に処理しますが、接続が失われたかどうか (マシンのイーサネット ケーブルが抜かれているなど) を判断するほどスマートではありません。
リモート I/O ステータスを取得するための唯一の選択肢は、ConnectedGroup_DataChange にサブスクライブして OPC アイテムの品質情報を監視することだと思いますが、もっと簡単な方法はありますか? 「-ping-こんにちはリモート I/O、まだそこにいますか?」のようなものです。
同様に、サーバーが稼働しているかどうか、または存在するかどうかを確認する方法が必要です( -ping-サーバーはありますか?) 現状では、ハンドシェイクは一切なく、クライアントは 2 つの単純な行でサーバーに接続します。 :
ConnectedOPCServer = New OPCAutomation.OPCServer
ConnectedOPCServer.Connect(OPCServerName, OPCNodeName)
サーバーの状態を返す関数を作成しましたが、KEPServerEX を終了した後でも常に 1 を返すようです。編集:プログラムを終了しても、実際にはサーバーが閉じられないことがわかりました。sysinternals スイートの Process Explorer を使用して、サーバーを見つけて中断しました。そうすることで、アプリケーションが .Connect 行でハングアップしました。実際に接続するまでサーバーの状態を取得することはできません。接続を試みる前にサーバーが存在するかどうかを確認するにはどうすればよいですか?
Public Function GetServerState() As String
Dim state As String = ConnectedOPCServer.ServerState.ToString
Return state
End Function
アップデート
最終プロジェクトの関連部分を共有すると思いました。C# で新しい Interop.OPCAutomation dll ラッパー クラスを作成することになりました。OPCAutomation dll の COM オブジェクトの性質により、通信に問題が発生すると、例外がスローされます。そのため、OPC 通信クラスのすべての関数に例外キャッチを実装しました。特定のエラー メッセージを探し、それに応じて対処します。
簡単に回復できる愚かな何かのためにアプリケーションをクラッシュさせるよりも優れています。
ServerState の場合、メッセージが何であるかは気にしないので、例外オブジェクトをキャッチしません。
これが私のステータス関数です:
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;
}
}
ご覧のとおり、「int state」は常に「1」を返すか、例外をスローするため、わざわざ何もしません。
私はすべての OPC 通信をスレッド上で行っているため、ロギング イベントをメイン スレッドに報告するスレッド セーフな方法を実装しました。
それでおしまい。それが誰かを助けることを願っています。