How to send message from gateway to Perspective session

Hi
I create a GIS system with perspective map and user can add/delete markup.
The markup include bedded view and a related UDT tag.
The UDT include two lat and lng property which get it's value from GPS device by MQTT.

I use map layer.view for markup that has lat and lng proms which should update by it's related UDT tag.

The problem is I can't simply bind those UDT(lat, lng) directly to my markup in map component views lost property because user create them in runtime. So the only thing I come up is when each markup UDT change it value, it send a message to perspective session and map component update its views base on that message.

So I wonder how I can send massage from gateway scope to perspective session.
Any idea or help will be appreciated.

1 Like

It’s a three-step process using system.util.sendMessage(), and it requires the sessionId you want to sent the message to.
In Gateway-scoped script:

# if clientSessionId is omitted, this call would update all Perspective sessions. You can also restrict delivery by other kwargs.
system.util.sendMessage(project='MyProject', messageHandler='LATLNGUPDATE', payload={'lat': <lat_value>, 'lng': <lng_value>}, clientSessionId=<sessionId>, scope='S')

In MyProject > Session Events > Message message handler with a name of ‘LATLNGUPDATE’:

# message key change to prevent confusion
system.perspective.sendMessage(messageType='SESSIONUPDATELATLNG', payload=payload, scope='session')

On your Markup component, configure a Message Handler (right-click > Configure Scripts) make a new Message Handler with a name of “SESSIONUPDATELATLNG” and select “session” for the scope. Within this script you can access the new lat and lng` values with

lat = payload['lat']
lng = payload['lng']
2 Likes

Thanks it’s very clear. Just one question.
Can I use system.util.sendMessage() in tag change script? I know it’s gateway scope but I heard it doesn’t work in tag script.

Even if you send a message to the session, if you cant directly correlate the instantiated markup to a UDT instance, then how can you know which markup should receive the message?

And if you CAN correlate the instantiated markup, could you not create a custom property on the map that reads your UDT instances and then a script transform that updates any instantiated markups that match?

I feel like that would be easier than sending messages

The post I believe you're referring to was attempting to use system.util.sendMessage to send a broadcast DIRECTLY to a component (Gateway > Component), when you must go the (Gateway > Session > Component) route.

2 Likes

For each markup type has embedded view with 3 prams:
Label
Lat
Lng
I create a folder for my markup UDT instance and name each instance with the Label. Actually when user press create button he create an instance of his Label in that folder. So matching them is easy just check UDT name with label.
I believe checking the all the list in custom property for every 5 sec is not good idea for performance.( For example I have 120 point and each point has lat lng which I should check for change and update my map)
Using message here is far ber performance.

1 Like

Ahh, you're definitely right here. I wasnt thinking of scale, much better to publish/subscribe than poll in this case.

1 Like

Hi
I just have one question left. If there are so many massages with one handler type but different payload sent at the same time what will happened?
Are they queued?

There shouldn’t be any queuing. assuming a setup along the lines of this:

list of payloads = []
for payload in list_of_payloads:
    system.util.sendMessage(project='MyProject', messageHandler='ONE', payload=payload, scope='S')

then those payloads would go out one at a time, in the order they are pulled from the list.

If something like a change script is invoking system.util.sendMessage(), then each of those invocations is a separate thread; this means that complex logic could result in race conditions because one thread could complete before another. It’s not a queue per se, just an asynchronous grouping of threads performing the same logic.

1 Like

For anyone else who is trying this, maybe I will save you some time during testing (which I have wasted a few now :man_facepalming:). On the system.util.sendMessage step - you can only test this in a launched client session NOT from designer per the documentation:

Messages cannot be received within a Designer. However, messages can be sent within the Designer in a script (assuming that read/write comm is enabled).

I was able to get this to work from GW Tag Change Event>Perspective Session Events>Message on a component> update my table binding.