Professional OPC
Development Tools

logos

Online Forums

Technical support is provided through Support Forums below. Anybody can view them; you need to Register/Login to our site (see links in upper right corner) in order to Post questions. You do not have to be a licensed user of our product.

Please read Rules for forum posts before reporting your issue or asking a question. OPC Labs team is actively monitoring the forums, and replies as soon as possible. Various technical information can also be found in our Knowledge Base. For your convenience, we have also assembled a Frequently Asked Questions page.

Do not use the Contact page for technical issues.

Random Disconnect from OPC server

More
08 Oct 2013 21:25 #1457 by dlbrown06
Sorry I'm not sure I understand what you mean when you say use two separate EasyDAClient objects. If I take out the operations I do in the event handler, there is no point of it.

I do not see inside e.g. your Collector::heartbeat, so I cannot tell which EasyDAClient object you are using there

The heartbeat is simply writing a single integer value to a tag. Matching what it just read from the triggered event. That first parameter verSender is the object that I am using by reference in the heartbeat method.
public static function heartbeat(&$opcSender, $plcVal)
{
   $_SESSION['PLC_HB_TIME'] = time();		
   $tagHeartbeatAck = $_SESSION['serviceConfig']['opcDevicePath'] . '.Status.HB02';
   return self::writeOpcItem($opcSender, $tagHeartbeatAck, $plcVal);
}
public static function writeOpcItem(&$opcSender, $tag, $val)
{
 
   try {
	$opcSender->WriteItemValue($_SESSION['config']['opc']['machine'], $_SESSION['config']['opc']['server'], $tag, $val);
   } catch (Exception $e) {
	$tmp = str_replace(array("\n","\t"," "), ' ', $e);
	LogHandler::error(__METHOD__, __LINE__, "Fault to write '{$val}' to opc tag '{$tag}': {$e}");
	return false;
   }
 
   return true;
}

Hopefully that helps clear up a few things. I'll add in and set the Isolated to true though.

Please Log in or Create an account to join the conversation.

More
06 Oct 2013 14:32 #1453 by support
Thank you.

I think that what is happening is similar to what has been reported to us by other customer as well. It appears that a background thread that is actually handling the OPC operations either hangs or terminates, which then causes the "read timeout", "write timeout", "or cannot connect topic" errors, which all basically indicate the same - that the background thread did not respond in a reasonable time. And, eventually, there is a crash, resulting from unhandled related condition to the first problem.

Unfortunately we were unable to repro it so far, but the hope is that the forthcoming stress test may reveal it.

I have one idea that you may try as a workaround. It is based on hypothesis that maybe the Write from the event handler is somehow colliding with the subscriptions or other stuff going on in parallel with it. Can you please try this:

1. Use two separate EasyDAClient objects. Separate out the object for operations you do from the event handler (I do not see inside e.g. your Collector::heartbeat, so I cannot tell which EasyDAClient object you are using there).

2. For both of these EasyDAClient objects, set their ClientMode->Isolated to true.

It is kind of desperate attempt, but I'd like to suggest at least something that can be done at the moment.

Please Log in or Create an account to join the conversation.

More
06 Oct 2013 13:39 #1452 by dlbrown06
It's happening every 1-2 hours. The heartbeat that its triggering off is changing every 5 seconds. Below is the event class:
class DEasyDAClientEvents {
 
	public $tagHeartbeat; //heartbeat
	public $tagInFloatSeq1; //collect from the plc
	public $tagCollectorFault; // fault bit written by the collector
	public $MsSql;
	public $Collector;
 
	public function __construct()
	{
		$this->tagHeartbeat = $_SESSION['serviceConfig']['opcDevicePath'] . '.Status.HB01';
		$this->tagCollectorFault = $_SESSION['serviceConfig']['opcDevicePath'] . '.Status.HB06';
		$this->tagInFloatSeq1 = $_SESSION['serviceConfig']['opcDevicePath'] . '.In.FloatSeq1';
 
 
		$this->MsSql = new MsSql();
		$this->MsSql->openConnection();
 
		return;
	}
 
	public function __destruct()
	{	
		if (is_object($this->MsSql)) {
			$this->MsSql->closeConnection();
			unset($this->MsSql);
		}
	}
 
	function ItemChanged($varSender, $varE)
	{
 
		try {
			$itemId = $varE->ItemDescriptor->ItemId;
		} catch (Exception $e) {
			$tmp = str_replace(array("\n","\t"," "), ' ', $e);
			LogHandler::error($_SESSION['serviceName'], __LINE__, "Failed to read subscribed item tag: {$tmp}");
			return false;
		}
 
		try {
			$itemVal = $varE->Vtq->value;
		} catch (Exception $e) {
			$tmp = str_replace(array("\n","\t"," "), ' ', $e);
			LogHandler::error($_SESSION['serviceName'], __LINE__, "Failed to read subscribed item val: {$tmp}");
			return false;
		}
 
		switch ($itemId) {
			case $this->tagHeartbeat:
				Collector::heartbeat($varSender, $itemVal);
		   		break;
	   		case $this->tagInFloatSeq1:
	   			Collector::handshake($varSender, $this->MsSql, $itemVal);
	   			break;
	   		case $this->tagCollectorFault:
	   			Collector::collectorFaultReset($varSender, $this->MsSql, $itemVal);
	   			break;
			default:
				LogHandler::warning($_SESSION['serviceName'], __LINE__, "Unknown subscribed item '{$itemId}' changed to '$itemVal'");
		   		break;
		}
 
	}
}

Please Log in or Create an account to join the conversation.

More
06 Oct 2013 13:31 #1451 by support
Hello, thanks for the information.
Is this happening always, often, seldom?
Can you post the DEasyDAClientEvents class?

Please Log in or Create an account to join the conversation.

More
06 Oct 2013 12:23 #1450 by dlbrown06
I've been trying to follow this through the rabbit hole and I think the initial com exception that starts all of this is:
exception 'com_exception' with message 'Source: OPCLabs.EasyDAClient.5.2 Description: Write not completed. This error indicates that it could not be verified that the requested write operation was completed during the timeout period. It is possible that the write operation will actually succeed or fail, but later. Increase the timeout period if you want to obtain positive or negative indication of the operation outcome. Other reason for this error may be that under heavy loads, topic request or response queue is overflowing. Check the event log for queue overflow errors (if event logging is supported by the product and enabled). 

That is when I do a single tag write based off a subscribed ItemChanged event. Then afterward it looks like easyopcl.exe is crashed and subsequent opc comms fail. For example I'm writing a heartbeat and I get this:
exception 'com_exception' with message 'Source: OPCLabs.EasyDAClient.5.2 Description: Cannot connect topic (timeout).

Is it possible that I am subscribing to this improperly causing the failure? The snippet of code used for the services to subscribe is below:
$opcCom = new COM($_SESSION['config']['opc']['comObjName']);
	$opcEvents = new DEasyDAClientEvents();
 
	if (!com_event_sink($opcCom, $opcEvents, "DEasyDAClientEvents")) {
		LogHandler::error($_SESSION['serviceName'], __LINE__, "com_event_sink failed");
	}
 
// 	$opcCom->SubscribeItem($_SESSION['config']['opc']['machine'], $_SESSION['config']['opc']['server'], $opcEvents->tagHeartbeat, 10);
	$tmp = array($opcEvents->tagHeartbeat, $opcEvents->tagInFloatSeq1, $opcEvents->tagCollectorFault);
	$opcCom->SubscribeMultipleItems($_SESSION['config']['opc']['machine'], $_SESSION['config']['opc']['server'], $tmp, 100);
 
	$_SESSION['PLC_HB_TIME'] = time(); // setting the inital time to start checking the PLC heartbeat to trigger a fault
 
	while (WIN32_SERVICE_CONTROL_STOP != win32_get_last_control_message()) {
		//User Loop
		usleep(10000); //10000 micro seconds = .01 seconds
		com_message_pump(1000);
 
		if (time() - $_SESSION['PLC_HB_TIME'] > $_SESSION['serviceConfig']['plcHbFaultTimeout'] + 5) { // 5 is the hb cycling time
// 			GknDataCollector::writeOpcItem($opcCom, $opcEvents->tagCollectorFault, 1);
			GknDataCollector::setCollectorFault($opcCom, 1);
			$_SESSION['PLC_HB_TIME'] = time() + 60;
		}
	}
 
	$opcCom->UnsubscribeAllItems();
	LogHandler::trace($_SESSION['serviceName'], __LINE__, "Service now unsubscribed to all change events");
 
	unset($opcCom);
	unset($opcEvents);

Let me know if there is anything I can do to help. I need to figure out a way to get this working.

Please Log in or Create an account to join the conversation.

More
06 Oct 2013 11:20 #1449 by support
This error can be legitimate when EasyOPC is working normally, and the target OPC server is not accessible (to RPC). In such case the "Source" (provided by the IErrorInfo associated with the error) will be the ProgID of the target OPC server. When methods that return multiple results (such as ReadMultipleItems) are used, in this case the method call itself will actually succeed, and the mentioned error will be in the Exception property of the individual result(s).

Or, it can be that EasyOPC component itself is not accessible to RPC - because it has crashed. In such case there will probably be no IErrorInfo associated with the HRESULT, and it will be returned directly even when calling methods that return multiple results (such as ReadMultipleItems).

It looks like that you have determined that this is the second case; in this case, EasyOpcl.exe should also disappear, and least temporarily, from the process list (which it should never normally do as long as it is in use by some client app).

There has been no specific resolution to the issue discussed in this thread. We can practically always fix problems that we can reproduce. Unfortunately, no repro has been achieved for this one. We are currently setting up a (networked) stress test with the intent to hunt for rare problems that we were not able to reproduce so far. It will take some time before any results come out of it, though.

Please Log in or Create an account to join the conversation.

More
05 Oct 2013 18:18 #1448 by dlbrown06
Has there ever been any resolution to this issue?

I've been getting this same sort of issue occurring on my end. I have a service that lags out that uses this and in the display logs it shows that Easyopcl.exe crashed. The version I'm using is 5.22.397.1.

The com exception that is brought up is 'exception 'com_exception' with message 'Error [0x800706ba] The RPC server is unavailable.'

Please Log in or Create an account to join the conversation.

More
31 Jan 2013 09:47 #1219 by support
This is very important to know. Please find it out.

Please Log in or Create an account to join the conversation.

More
31 Jan 2013 09:43 #1218 by algorithmica
I have not verified this explicitly now with the new version but last time we checked, it was ReadMultipleItems that seemed to enter an infinite loop.

Please Log in or Create an account to join the conversation.

More
31 Jan 2013 09:40 #1217 by support
Thank you.
And, just to verify, the code is not "blocked" anywhere (specifically, in ReadMultipleItems) - that is, you know that the loop that calls this piece of code is running well, right? Or does it "hang" somewhere?

Please Log in or Create an account to join the conversation.

Moderators: support
Time to create page: 0.064 seconds