How can I know if the plc connection is lost once I subscribed a tag? - opc

I created a client application that has a subscription to monitor several tags through the OPC UA server(c#). If the connection between the OPC server and the PLC is lost while the client is running, the client stops receiving information from the server and it is never notified that the plc is not reachable any more.
I am evaluating to implement a periodic reading operation for one tag through the OPC server to actually know if the plc connection is active or not, but if there is a native mechanism in OPC UA I would like to avoid it.
Is there a way (eg. an event) to notify the client that the connection with the plc is lost for the running subscription?

A compliant OPC UA server must send notification with one of the "Bad" status codes, when the connection to the target system is lost. This is the normal notification event, same channel as the "good" ones, it just carries a different DataValue that happens to have the StatusCode with corresponding bits set so that it indicates a problem.
So, you need to check the StatusCode in the incoming notifications. If you are already doing that, but the server truly sends nothing in case of communication loss, you need to complain to the server vendor, because such behavior isn't really acceptable for any serious server.
Note: There are ways to specify a data change "filter" when subscribing to monitored item, and you can tell whether you want to be notified e.g. when just the timestamp changes and not the value, etc. But no matter how the filter is set, changes in StatusCode are always sent. Therefore the problem cannot be in having incorrect filter set.

Related

Is there an out of the box solution for Client-Client communication using the QUICKFIX library?

I'm trying to build a entirely contained trading simulator using quickfix/J. The systems ought to consist of 2 client applications (a market/exchange and a broker) as well as a router (server/acceptor). In particular I'd like to know:
Client-Client communication
How the two clients can communicate to each other, but the server handling all the messaging logic, ie. messages should go through server and it should decide where and how to forward messages. I ought to be able to pass a targetID in FIX message, and the server app should handle routing to desired client.
Multiple clients on same port
Have multiple clients connected on same port but messages should only go to a particular sender comp Id ie. clients should not be privy of communication from other clients.
I've already set up the acceptor, and 2 clients. I know I could do this programmaticaly using plain old Java but I'd like to leverage the quickfix library and would like a relativly out of the box solution.
MVP: client (broker) sends fix message through the acceptor(router), message is processed and forwarded to a particular market, market recieves message through server and does some business logic, market sends fix message back to client through acceptor.
ps: I like the quickfix library but I'm very flexible if there any other library/languages you'd recommend
Short answer: QuickFIX/J (as far as I can tell similarly QuickFIX or quickfix/n) will not route messages based on tags. This has to be implemented in your application code.
Edit: with regard to your second point. There is no problem having your FIX server listening for multiple FIX connections on the same port (This applies for QuickFIX/J and I guess also the other language variants.) Sessions are addressed via the SessionID so it is ensured that only the correct FIX Session gets its messages.

Modbus client and server with message forwarding

I am working on a legacy modbus program for an industrial SCADA system.
Currently, the c++ program acts as both a modbus TCP server and client.
Client behaviour:
It reads from a number of vendor PLCs (servers) on site, performs calculations and sends control commands back to the PLCs based on the data received across the site.
Server behaviour:
responds to a variety of TCP read and write requests from web interfaces and laptops on site.
Until now, this has worked fine, but we have recently installed a logging client on the network which polls our program very frequently (sub-second) and this has revealed timing issues: the program can potentially take a very long time in its client loop performing calculations and reading PLC values before acting as a server and responding to incoming requests.
Easy solution would be to split the programs into a modbus server and client instance, and keep them both running on the same embedded PC.
The issue I have is that the remote web interface (HMI) must be able to control the behaviour of vendor PLC 2 and Vendor PLC 2 will only allow one TCP connection from the embedded PC. In the past the program has handled writes requests from the HMI by forwarding them on to the PLC 2 via the open socket.
I'd be keen to gather thoughts on best practices here.
My thinking:
the modbus server program will need to respond to the HMI requests and somehow store the information required for vendor PLC 2, and it will also need to set a status register to inform the modbus client that there is data for vendor PLC 2.
The modbus client program will need to read the status register (and data) from the server and pass this on to vendor PLC 2.
Am I heading in the right direction?
Without having details on your implementation I can only guess the problem is that your program is single-threaded, and delays are caused by waiting responses from PLCs.
So, if my assumption is correct, you need to switch to 'select' function and redesign your software to be totally async. You have to put all sockets (both connected and accepted) in a FDs set and wait events on them.
win32:
https://learn.microsoft.com/en-us/windows/desktop/api/winsock2/nf-winsock2-select
linux:
https://www.opennet.ru/cgi-bin/opennet/man.cgi?topic=select&category=2
I've written the same app ages ago on win32 (but without calculations) and it easily processed about 200 PLCs, working on the same machine with SCADA.

websocket communication between clients in distributed system

I'm trying to build instant messaging app. Clients will not only send messages but also often send audios. And I've decided to use websocket connection to communicate with clients. It is fast and allows to send binary data.
The main idea is to receive from client1 message and notify about it client2. But here's the thing. My app will be running on GAE. And what if client1's socket is opened on server1 and client2's is opened on server2. This servers don't know about each others clients.
I have one idea how to solve it, but I am sure it is shitty way. I am going to use some sort of communication between servers(for example JMS or open another websocket connection between servers, doesn't matter right now).
But it surely will lead to a disaster. I can't even imagine how often those servers will speak to each other. For each message server1 should notify server2, server2 should notify client2. But things become even worse when serverN comes into play.
Another way I see this to work is Firebase. But it restricts message size to 4KB. So I can't send audios via it. As a solution I can notify client about new audio and he goes to my server for it.
Hope I clearly explained the problem. Does anyone know how to solve it? Or maybe there are another ways to build such apps?
If you are building a messaging cluster and expect communicating clients to connect to different instances of the server then server-server communication is inevitable. Usually it's not a problem though.
First, if you don't use any load balancing your clients will connect to the same server 50% of time on average (in case of 2 servers).
Second, intra-datacenter links are fast and free in all known public clouds.
Third, you can often do something smart on the frontend to make sure two likely to communicate clients connect to the same server. For instance direct all clients from the same country to the same server using DNS load balancing.
The second part of the question is about passing large media files. It's a common best practice to send it out of band - store on the server and only pass the reference to it. Like someone suggested in the comment, save the audio on the server and just send a message like "audio is available, fetch it from here ...". You don't need to poll the server for that. Just fetch it once when the receiving client requests it.
In general, it seems like you are trying to reinvent the wheel. Just use something off the shelf.
Let all client get connected to multiple servers and each server keeps this metadata
A centralized system like zookeeper stores active servers details
When a client c1 sends a message to client c2:
the message is received by a server (say s1, we can add a load balancer to distribute incoming requests)
s1 will broadcast this information to all other servers to get which server the client c2 is connected to OR a better approach to use consistent hashing which decides which server the client can connect to & in this approach message broadcast is not required
the corresponding server responses to server s1 (say s2)
now s1 sends the message m to s2 and server s2 to client c2
Cons of the above approach:
Each server will have a connection with the n-1 servers, creating a mesh topology
Centralized system (zookeeper) becomes a single point of failures (which is solvable)
Apps like Whatsapp, G-Talk uses XMPP and TCP/IP.

What does my OPC Server need to do after OPC Client restores lost connection? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 9 years ago.
Improve this question
I have my own OPC Server written using the SLIK-DA4 ActiveX control in VB6. It hosts quite a large collection of tags (probably 2,000).
A customer uses a Siemens OPC client to connect (no private security). Everything goes fine and subscription reads appear just fine on the client.
Some time later, the IP link is lost between client and server for a while. However, the customer is telling me that when the link recovers, they then have to "do something" on the OPC client to get it to start subscribing again, after which things return to normal.
... Yes, I know, I'm trying to find out what they mean by "do something" !!
However, in the meantime, I'm trying to think of what I might not be doing correctly in my server code to handle this situation. My tag values don't update too often in the attached field equipment, so is it possible that, on reconnection, the client isn't receiving any callbacks simply because there are no tag changes taking place ?
On recovery of the link, how can I get the server to push an up-to-date status for all tags to the client rather than rely on someone "doing something" on the client end ? Do I need to use the OnConnect event and then SetVQT(,,sdaSGood) for all tags, or will this not have any effect ?
Thanks
When the OPC server receives a new connection (which seems to be the case), or more precisely, when the OPC client it creates an active group and puts items in it, the server is supposed to send an initial notification about each item (value/timestamp/quality, or error) - even if it has not changed recently.
If you are developing the server using a reasonable OPC toolkit, however, this should be taken care of automatically by the toolkit code. It certainly makes no sense to try to change the quality of the tags just because the OPC client had connected. The quality in the VQT should reflect whatever comes from your underlying system, or the communication problems communicating to THAT system, but not anything between the OPC server and the client.
It may also very well be a problem on the client side - simply not resilient enough to handle certain situations. The authoritative way to tell what is happening (and put the "blame" into the direction of the server or the client) would be place an OPC Analyzer (available from OPC Foundation to OPC Members) in between, and log the OPC calls and check which side is not behaving right.
what they mean by "do something"
I think it means that customer needs to restart the client, create a group and add tags. But this is how things should be, because OPC Specification doesn't say anything about handling of connection breaks. It has only description of interfaces which can be used to check connection (server) status (e.g. IOPCServer::GetStatus). Typically, clients reconnect (create a new connection with new group and add tags) automatically, but only if they have been noticed that connection was lost.
a "re-open" request from their OPC Client
You can ask someone from Siemens to provide you quotation from OPC Specification where "re-open" mechanism and/or interfaces are described. Because I don't remember such notations in specification.
But if "re-open" means reusing of old connection (i.e. DCOM objects left from old connection) then I may assume the following situation:
client and server interacts properly
connection breaks
server sends OnDataChange callback to client and receives an error (something like "RPC service is unavailable")
server just stops sending of OnDataChange callbacks and do nothing with DCOM objects related to current connection
connection restores
client still can call server using existing DCOM objects but doesn't receive OnDataChange callbacks
customer need to restart client manually to repair connection
In such case you (or toolkit) should remove all objects related to broken connection or don't stop sending of callbacks.
When IP changes ,try to reconnect the OPC Server or Make your OPC Server IP address as static

PLC data communication with a remote server

How can I interact with a PLC to send and receive data to/from a remote server(PC).
For example a robot that have a PLC and want to interact with a server that placed at near room with a wireless communication.
Data must move all over the time. PLC sending the data to the server and server must sending back the result of computation on the data to PLC.
review : My PLC brand is Delta but its model has not been selected yet .
A common scenario is that the manufacturer provides an OPC server for the PLC. You should check their website once you know the model. Then it is just a matter for you to create an OPC client.
A good way to start is to get a free OPC server simulator like the one from Matrikon. It doesn't need any hardware. OPC is a standard interface (although there are often some minor variations between manufacturers) - if you can get your client to work with the test server you can probably get it to work with the PLC.