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.

× If you are developing in .NET, but are using the OPC-UA (OPC Unified Architecture), please post in the QuickOPC-UA category instead.

When I interrupt subscription to OPC DA server item(s), I cannot re-subscribe.

More
11 Feb 2024 19:38 #12550 by support
Hello.

Re 0) Regarding the exception: Yes please upgrade first to version 5.72 (or 5.80 which should be out in a few weeks). If it persists, report it again and we will troubleshoot.

Re 1) The fact that you get no event all make it look even more like a sub-optimal behavior on the server side.

Re 2) Windowed application can relatively easily detect a proper termination, and close the connections in an orderly way. So that's what OPC Expert does. Console application has it more difficult to achieve, but it is doable. Look e.g. here: stackoverflow.com/questions/4646827/on-exit-for-a-console-application .

Re 3) same as Re 1).

To your last question (wait after Unsubscribe): This a *very good* question. All SubscribeXXXX/UnsubscribeXXXX are, at least potentially, asynchronous, meaning that the actual operation might be performed after the method returns. Without this behavior, some users were complaining that whey they tried to do the shutdown, the application has sometimes blocked. With synchronous design, this is unavoidable, as the "orderly" shutdown needs to cooperate with the server, and if the network or the server blocks, the methods blocks too. The current design is asynchronous. So it does not block. And the recommendation is to add some wait time. We currently give you no way tell when/whether the "unsubscribe" was actually made. But when things go normally, I would say it would be done in less than 2 seconds. And if it is not, it would then takes so long that you would not want to wait to the end anyway.

Best regards

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

More
07 Feb 2024 14:06 #12543 by mut9bu
Hello, first thank you so much for the detailed answer.

Here The answers to your questions:

0) Related to the exception: Currently I am using V 5.71.401. We are planning an update in short term.

1) Related to the Error what I get for unseccusfull resubscription, after subscription interrupted:
I get really no error. (I have programmed all error handlings). The subscription seems to be made, (I don't know perhaps not). But I get no event on to the client.ItemChanged += client_Main1_ItemChanged eventhandler. The app is just waiting (also no initial value of the item is coming), and after programmed subscription time exiting.

2) I have tried following with OPC Expert:
I have subscribed to the same remote CNC machine with the same item. During subscribing was active I have closed the program
a) With window close button X
b) With End task from Task Manager
In both cases OPC Expert showed a short dialog with Disconnecting from... (I think unsubscribing is inclueded) before closed.
In both cases when I restarted OPC Expert and subscribed to the same machine and same item, subscription worked without problem.

3) For my console app, I have measured one time and it was about 12-13 minutes I had to wait for resubscribing.

Result: I think the OPC server (Rexroth CNC OPC Server OPC.IwSCP.1{108fb1cf-f509-4d86-b1da-54bf1dd67a8d}) has a special reaction to interruption of subscriptions.
But acc. to my Test OPC Expert can manage this, i think with correct unsubscription and perhaps disposal.
I can take measures for my app. , that when it is closed unregularly the unsubscription and disposal is done.

Here one last question:

For a correct unsubscription process is client.UnsubscribeAllItems() enough? Or should I sleep the thread addiitionally few seconds before exiting the app with Environment.Exit(0) ?

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

More
07 Feb 2024 12:22 #12542 by support
Hello.

The "easy" part is the exception. This is almost certainly a bug in QuickOPC. We have recently fixed something similar. Please indicate which version and build you are using. Based on that, I will either direct you to a newer version, or we will try to reproduce it and consequently fix it.

With the remainder of your post, you have come into fairly complicated area, which I will try to explain briefly below.

If you close the console window, obviously the finalization code you have does not get executed. Our library does not do that either - on reason for it being that there are various types of applications, and the termination procedures are always different (if available for "hooking" to the developer at all). An ideal user code should hook the "unexpected" termination, and perform whatever cleanup actions are needed (in this case, doing UnsubscribeAllItems, and Dispose, or both).

However, with COM-based OPC, normally none of the above is actually necessary. This is because the COM/DCOM infrastructure "sees" the process termination, and it always make the so-called IUnknown::Release calls on all out-of-process objects used by the terminating process. So, the OPC server should see a behavior similar to how normal OPC client shutdown looks like. But there is one difference: The COM/DCOM infrastructure does not know the details of OPC interfaces. It does not know that a fully proper shutdown should also involve calls to RemoveItems and RemoveGroup. So it does not do this on behalf of the terminating client. But even this is normally not a problem, because well-written OPC servers will interpret the last "Release" on a Group or Server object accordingly, and will not insist on the items and groups bein explicitly removed.

So in this sense, I am surprised by the behavior you are observing. It looks like that 1) the server is not capable of the auto-cleanup described above, and 2) in addition, it has some limitation that does not allow repeated subscription.

Questions:
1) What error are you actually getting?
2) Can you try the same with some other OPC server - such as our simulation server?
3) How long do you need to wait before the functionality is restored? Note: DCOM has "famous" 6-minute timeout, which (in simple terms), is the amount of time it needs to recognize that a remote party is "gone". This can kick in in situations like physically disconnected network cables; but, as I wrote above, to my knowledge, not in the case of untidy process termination.

Leaving aside the possible termination handler, your code appears to be correct (both with and without the call to UnsubscribeAllItems).

Regards
The following user(s) said Thank You: mut9bu

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

More
06 Feb 2024 14:27 - 07 Feb 2024 11:58 #12541 by mut9bu
Hello
I have an interesting finding regarding subscription to OPC DA server item(s). With my code below: (Net Framework 4.7.2 Console app)

1) When I subscribe to a dynamic changing item let say for 10 seconds, and the time is over, and so the console app exits with Environment.Exit(0), I can subscribe once more to the same item with restarting console app, without problem. (In this case I do not unsubscribe to the items with client.UnsubscribeAllItems() after Thread.Sleep(10000))
I have tried this behaviour 8-10 times and always worked.

2) When I subscribe to the same dynamic changing item again for 10 seconds, and , interrupt the code (in my case close the console window) before the time is over, then I cannot re-subscribe to the same item any more. After waiting long time perhaps it is possible to resubscribe again.(In this case I also do not unsubscribe to all items with client.UnsubscribeAllItems() after Thread.Sleep(10000))

3) When I activate the client.UnsubscribeAllItems() after Thread.Sleep(10000), I get a very long exception. I have attached this as a file in the attachement.

My questions:
1) Why is the resubscribing working in case 1) and not in case 2) ?
2) Why is the client.UnsubscribeAllItems() causing to the error in my code?
3) What should be the correct unsubscribtion way for my code, especially for the possibility that my app could not be closed properly?
public  void subscribe_items(string ip)
        {
            try
            {
                using (var client = new EasyDAClient())
                {
                    client.ItemChanged += client_Main1_ItemChanged;
 
                    Console.WriteLine("Subscribing item changes..." + ip);
                    client.SubscribeMultipleItems(
                        new[] {
                            new DAItemGroupArguments(ip, "OPC.IwSCP.1", "IndraMotion_MTX_P60,SPA1,2,P-0-0440,D", 1000, null),
                            });
                    Console.WriteLine("Processing item changed events for 1 minute...");
                    Thread.Sleep(10 * 1000);
                    //client.UnsubscribeAllItems();   // This line I am just activating in case 3) 
 
                }
                Console.WriteLine("Finished.");     
            }
            catch (Exception ex)
            {
                // Error handling
                Console.ReadLine();
            }
            // Instantiate the client object.
        }
 
        // Item changed event handler
        public string array_item_to_web = "array_item";
 
        public void client_Main1_ItemChanged(object sender, EasyDAItemChangedEventArgs e)
        {
            Console.WriteLine("item changed");
            if (e.Succeeded)
            {
                try
                {
                    using (StreamWriter sw = File.AppendText(@"D:\test\opcda_testlog_test.txt"))
                    {
                        // sw.WriteLine("value: " + e.Vtq + " " + Convert.ToString(DateTime.Now));
                    }
                    item_value = e.Vtq.ToString();       
                    Console.WriteLine(e.Vtq);
                    Console.WriteLine(e.Vtq.Value);            
                }
                catch (Exception ex)
                {
                    //Error handling
                }
            }
            else
            {
               //Error handling
            }
        }
Attachments:
Last edit: 07 Feb 2024 11:58 by support.

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

Moderators: support
Time to create page: 0.052 seconds