system.util.sendMessage()/sendRequest() issues/questions

Ok, so I've gathered that sendMessage and sendRequest are essentially the same function, except the request sends back a response. Ultimately, I want to use sendMessage (no response needed), but I'm using sendRequest temporarily to use the response for troubleshooting.

I have four gateways set up for testing, all together on a gateway network, but so far just trying to message between two of them, and so far just one-way (gateway1 to gateway2).

On gateway2, I set up a message handler. On gateway1, I set up the sendRequest on a tag alarm acknowledge event script (which I understand to be a gateway-scoped script). This doesn't work... however, when I use the exact same code in Designer in the Script Console, it works as intended. Code is virtually cut/paste, except in the Script Console I hardcode the contents of the payload vs loading from event parameters. If it was a payload issue, I would expect the handler to be triggered and have a failure there. In the gateway status page for scripts, it's showing that the handler is not being triggered at all when triggered by the ack event.

Questions:

  1. Any ideas why the difference in script scope would impact this?

  2. Other than needing to be a dictionary, are there limitations on the payload size?

  3. The association between project and handler appears to be done by name, not some unique identifier...? I re-imported the project on gateway2 under a different name, and instead of registering the handler to the new project (gateway web page -> status -> gateway scripts -> message handler), it only showed the original project/handler combo. It wasn't until I renamed the handler that it showed the new project/handler combo. Is this normal/expected?

The event object you get is not a simple dictionary, so it's possible there's an issue with data type coercion, but there should be an error message on the sending side. Seeing your exact code in both situations could be helpful.

I would recommend adding your own instrumentation with loggers (system.util.getLogger) over strictly trusting our status pages. While they certainly should be accurate, it's usually faster and more reliable to trace what's happening with your own logging.

Not explicitly, but asking this question makes me nervous. I would not send more than ~kilobytes of data via scripted messaging directly; it's really not intended for anything more than control messages/dictionaries with tens to hundreds of keys. If you're trying to send large binary payloads, you should find another channel.

I don't quite know what you're asking with this, but yes, the only "lookup" is by name. This is generally true throughout Ignition. The handler probably didn't show up after the import because it hadn't actually been invoked; either invoking it or renaming it should cause it to show up. That is, if you found any discrepancy here it's just in the change detection on the status page, not an issue in the fundamental execution code.

So I am using the logger in the event handler and the message handler. What appears to be happening is it is triggering the message handler on the local gateway1, even though I'm explicitly setting the remoteServer parameter to gateway2. Again, what I have works from a Script Console, just not from the event handler, so it seems to be related to the execution scope. I ended up creating the message handler (with the same project and handler name) on gateway1 just to help troubleshoot, and it seems to be getting triggered.

event script:

 def alarmAcked(tag, tagPath, alarmName, alarmEvent, alarmPath, ackedBy, missedEvents):
 	servers = ["gateway2"] #system.net.getRemoteServers(0)
 	myDictionary = {'tagpath':str(alarmEvent.getSource()), 'ackedBy':"admin", 'notes':alarmEvent.notes}
 	response = system.util.sendRequest(project = 'project', messageHandler = "AckHandler2", scope="G", payload = myDictionary, remoteServers = servers)
 	logger = system.util.getLogger("mylog")
 	logger.warn(response)
 	logger.warn("HI!")

message handler:

 def handleMessage(payload):
 	logger = system.util.getLogger("mylog")
 	logger.warn("HI FROM HANDLER!")

Don't worry too much about my payload size question... I'm not trying to use it to replace FTP :slight_smile: I'm just trying to ascertain if it's limited, for example, by MTU for a single frame. Hundreds of keys - potentially several kb - is plenty.

One difference between sendRequest and sendMessage when targeting remote servers is that sendRequest can only target a single remote server, where sendMessage can broadcast.

Fix that.

1 Like

Hi Phil... good catch!

I was really pulling my hair out here... it was a typo all along! The parameter is singular (remoteServer, not remoteServers) in sendRequest! Somehow I did it correctly in the script console, and missed it in the event script! Thank you!

2 Likes