Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Best pratices to create WebSocket client actor

Solved!
Go to solution

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.

 

Simplified schema network.png

 

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 :

 

SEQ_DIAG.png

 

 

  • 1st problem: how do I pass the IP address and port as a parameter to my overrided Actor Core method that is currently initiating the link ?
  • 2nd problem: I don't know how to make my methods only capture messages that concern them
  • 3rd problem : My WS Client Actor is not stopped correctly. It closes normally but the project keeps a ProxyCaller running

Here's what I started doing (GetPN is just another method like GetPower) :

Actor Core overrided.png

Project.png

Thank you in advance for any ideas you can give me 🙂

Download All
0 Kudos
Message 1 of 9
(2,530 Views)
Solution
Accepted by topic author syuiopwdfghj

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.)

0 Kudos
Message 2 of 9
(2,500 Views)

Hello @BertMcMahan,

 

Thank you for your message.

  1. Both solutions work, each has its flaws. The first requires a boolean in the private data to store the state. It's not great but it works as you say. The problem with the second is that if you forget to initialize, the WebSocket reads nothing without error... A problem for my project.
  2. I managed all of the messages received in the core actor which then dispatches the messages as required.
  3. I concluded after a few weeks of use on the actor framework that the presence of a helper loop in the actor core requires the management of a Stop event (as we can see in the tutorials Youtube)

Thank you again for your enlightening answers!

0 Kudos
Message 3 of 9
(2,418 Views)

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.

0 Kudos
Message 4 of 9
(2,401 Views)

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.

0 Kudos
Message 5 of 9
(2,386 Views)

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.

Message 6 of 9
(2,376 Views)

Thanks for your response, I still need to familiarize myself with the actor framework. It was evident 🙂

0 Kudos
Message 7 of 9
(2,347 Views)

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 🙂

Message 8 of 9
(2,328 Views)

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

Message 9 of 9
(2,296 Views)