01-12-2024 07:33 AM
Hello everyone,
I'm completely new to the Actor Framework and I'm faced with a problem of choice.
I have a Root Actor that launches one or more nested actors (WS Client Actor).
A WS Client Actor must first initialize the WebSocket link to a defined device that behaves like a WebScoket server.
I want my WS Client Actor to read the messages sent spontaneously by the hardware equipment.
I want to be able to send messages to retrieve infor mation from my WS Server as follows :
Here's what I started doing (GetPN is just another method like GetPower) :
Thank you in advance for any ideas you can give me 🙂
Solved! Go to Solution.
01-12-2024 01:08 PM
For #1, you can initialize it in one of two ways:
1- Send an "init" message to tell the Actor what the IP address is
2- Set the IP address as a property of the Actor object prior to launch with an accessor
I'd recommend number 2. Don't forget that Actors are classes. Prior to launching them, you can set properties, run methods, etc as much as you want. Number 1 works, but then you need to maintain state in the actor of "Initialized" vs "not initialized". In my experience, it's simpler to kill and restart an Actor with new settings than to be able to transition a "living" Actor to a new set of initialization parameters.
For #2- I'm not very familiar with Websockets specifically, but if you're connecting to a dedicated IP address, then wouldn't all messages be of interest? The simple answer is that you'll need to receive every message, then decide what to DO with that message- so if you get a message you don't care about, just don't do anything at all.
For #3, apologies but I don't have time to review your code right now but it's probably your helper loop. Stopping the Actor will halt Actor Core, but it won't abort it. Your helper loop will keep running until you either click the Stop button (not Abort, but Stop- the one you have wired into the Stop terminal) or either of those two functions returns an error.
You'll need to signal the helper loop to abort somehow. If those functions are blocking, then you'll need to find a way to abort them as well. What happens if the "Read" function just never returns anything? You'd end up with a locked Actor.
I'd say, make a Queue or Notifier with a boolean data type, and add a Dequeue Element or Wait on Notification at the start of your helper loop. Set the timeout to 0 so it doesn't block, it just checks to see if anything has arrived. If so, it can abort (add another input to your Or at the Stop terminal). After Actor Core, add an Enqueue Element or a Send Notification with a TRUE constant. When Actor Core returns (meaning the Stop message was received) then it'll generate the "stop" signal for your Helper loop.
Alternatively, you could close the WebSocket connection after Actor Core (which you probably should do anyway) which I'd guess would make the Read function return an error.
(Then again perhaps you're trying to do this already in Stop Core? But that executes after ALL of your Actor Core children are done executing, so you can't use it to stop a helper loop within Actor Core.)
01-29-2024 02:59 AM
Hello @BertMcMahan,
Thank you for your message.
Thank you again for your enlightening answers!
01-29-2024 10:23 AM
For the problem you mentioned of not initializing, just add a check in Pre-launch Init to see if the IP address can connect. If it cannot, then have Pre-launch Init return an error. This will prevent the Actor from launching, and your "Launch Actor" function will return that message. Your calling code will know immediately that it tried to launch an Actor and it didn't work, so you can handle the error right away.
01-30-2024 03:12 AM
Yes, it's true ! Thank you for this tip which I implemented immediately. The problem is that my error stops all the actors and not just the one in error.
01-30-2024 10:12 AM
That's the standard behavior for the Actor Framework- any unhandled error passed upstream stops the whole batch. You'll need to override Handle Error.vi in any Actor that needs to handle errors.
01-31-2024 02:57 AM
Thanks for your response, I still need to familiarize myself with the actor framework. It was evident 🙂
01-31-2024 11:21 AM
That "gotcha" gets us all when we first start using it. Having a single minor error shut down your whole application is definitely a surprise the first couple times it happens 🙂
02-03-2024 01:24 AM
Hi,
I don't know if this is going to be useful for you but at LS Instruments we have developed an Actor Framework based WebSocket library. It is based on a Publisher/Subscriber approach. In order to handle messages form the WS Server you will have to subclass a certain Abstract message. Clearly you will be able also to send messages to the WS server.
The GitHub repository is here:
https://github.com/LS-Instruments/WebSoket-Actor
wherein you can find the corresponding documentation.
There is also a VIPM package that you can obtain form the VI Package manager
https://www.vipm.io/package/ls_instruments_ag_lib_websocket_actor/
Cheers,
Andrea