Jump to content
parsec

Network streams - multiple windows executables to compact RIO target

Recommended Posts

Hi,

I am trying to connect multiple windows executables to a single compact Rio target using network streams (Only one direction; windows executables send data, CRio receives data). This functionality works fine when using stream senders in the dev environment.

I have seen that doing this successfully requires the use of a context name in the endpoint url that contains the application name, however I am having trouble figuring out how to do this since all of the examples I have seen deal with multiple (windows) executables attempting to establish streams to other executables. I have attepted to add context names on both sides (executable and Rio) without much success.

Can anyone point me to an example of what needs to be done? I have tried a number of things to no avail. I am unsure of the role of the writer name and writer url in making all of this work.

I seem to have trouble attaching images;

http://imgur.com/a/9V6vu

 

Share this post


Link to post
Share on other sites

I can't see your code as our IT blocks most file sharing sites.

It sounds like you are trying to do is in the "Shared Variable" example. I expect you would need to add buffering on the cRIO side to ensure you received all messages.

Share this post


Link to post
Share on other sites
8 hours ago, parsec said:

Hi,

I am trying to connect multiple windows executables to a single compact Rio target using network streams (Only one direction; windows executables send data, CRio receives data). This functionality works fine when using stream senders in the dev environment.

I have seen that doing this successfully requires the use of a context name in the endpoint url that contains the application name, however I am having trouble figuring out how to do this since all of the examples I have seen deal with multiple (windows) executables attempting to establish streams to other executables. I have attepted to add context names on both sides (executable and Rio) without much success.

Can anyone point me to an example of what needs to be done? I have tried a number of things to no avail. I am unsure of the role of the writer name and writer url in making all of this work.

I seem to have trouble attaching images;

http://imgur.com/a/9V6vu

 

Every endpoint needs a name.

Network Streams are one-to-one: One writer sends data to one reader. Between this pair, only one needs to specify the URL.

I presume that your cRIO's IP address is 10.1.17.201? This is what I recommend:

  • You don't need any context names.
  • On your cRIO, set the reader name to "myreader".
  • On your cRIO, do not wire anything into writer url.
  • On your PC, set your writer name to "mywriter"
  • On your PC, set your reader url to "//10.1.17.201/myreader"

Share this post


Link to post
Share on other sites

The context is just any string, its not the application name. It also only matters if there is >1 exe running on a target, so you never need it for the cRIO side. On windows using the application name only works if its unique -- simpler to pick a random number.

Since streams are 1:1 if you want to connect multiple senders simultaneously you need either multiple hardcoded reader streams on the cRIO or you need to define your own listen+accept scheme just like TCP. I would just use TCP but if you like streams you would do this:

  1. on crio create a writer stream called "streamaccept"
  2. on windows machine connect to streamaccept using reader endpoint <random1>:<random2>
  3. on crio, create <random3> and send it over the streamaccept stream to windows, then launch a process to handle that stream (reader <random>)
  4. on windows receive <random3> from streamaccept and create a new write endpoint <random4>:<random5> which connects to <crio>/<random3>. Close the <random1>:<random2> endpoint
  5. connection established, send data
Edited by smithd

Share this post


Link to post
Share on other sites

I think I may have failed to explain my problem clearly enough. I acknowledge that streams are 1:1, which is why I have a handler to create multiple independent streams on the Rio.

It works as follows:

-A random string is generated, which becomes the reader name of the open endpoint on the CRio.

-This random string is written to a shared variable.

-A windows VI or executable reads that shared variable to know the open endpoint name on the CRio. It then establishes a connection with the listening endpoint on the Rio. 

-The Rio then generates a new random string, which becomes a new open endpoint. This is written to the shared variable and the cycle continues.

The problem is that all of this works fine when connecting multiple windows VIs running in the dev environment to a single CRio. Multiple executables on different computers connecting to a single CRio also work fine. Where I get into trouble is trying to run multiple executables on a single computer connecting to the CRio, or an executable and the dev environment connecting to the single CRio.

All of the reading I have done points to this having to do with the context name. The context name is "LabVIEW" when running in the dev environment, which works fine. When running executables, it is apparently the application name, and this seems to be the reason it falls over in the end.

There are many forum posts about the topic elsewhere, but I can't seem to adapt their fixes to my situation, i.e. Multiple executables to single Rio.

http://forums.ni.com/t5/LabVIEW/Network-Streams-error-314350-Many-executable-to-One-executable/td-p/3235867

I have cleaned up my relevant code to make the problem more clear. Please forgive my inability to attach files here.

http://imgur.com/a/pv5iA

Share this post


Link to post
Share on other sites

Assuming I'm understanding you correctly, you need to read and comprehend this, basically:
http://zone.ni.com/reference/en-XX/help/371361N-01/lvconcepts/endpointurls/

But to point you to the right place:
" Note  Only one application on each computer can specify the default context. Therefore, if you have multiple applications on a single computer that use network streams, you must assign a URL instead of a name to each endpoint in those applications "

So your streamname shouldnt be <randomnumber> it should be //localhost:<random1>/<random2>

I don't know how fast your code starts up but if you are going to use a shared variable I'd suggest setting your endpoint create to a fast timeout (1-2 sec) in case two exes try to claim the endpoint at the same time.

Edited by smithd

Share this post


Link to post
Share on other sites
34 minutes ago, smithd said:

Assuming I'm understanding you correctly, you need to read and comprehend this, basically:
http://zone.ni.com/reference/en-XX/help/371361N-01/lvconcepts/endpointurls/

But to point you to the right place:
" Note  Only one application on each computer can specify the default context. Therefore, if you have multiple applications on a single computer that use network streams, you must assign a URL instead of a name to each endpoint in those applications "

So your streamname shouldnt be <randomnumber> it should be //localhost:<random1>/<random2>

I don't know how fast your code starts up but if you are going to use a shared variable I'd suggest setting your endpoint create to a fast timeout (1-2 sec) in case two exes try to claim the endpoint at the same time.

I have tried this but I still can't get it to work. I am creating two random strings, so the reader name on the Crio is //localhost:random1/random2

I send random1 and random2 to the Exe/Dev environment host, so that it connects to the reader url    //CRIo-IP:random1/random2

I still get the same problem. One stream connects fine, but when I attempt to connect a second stream, I get the 314350 error.

Every application now has a unique context name and endpoint name, yet when running a second host it still claims the endpoint context is occupied.

 

 

Error -314350 occurred at Create Network Stream Writer Endpoint in testingendpoints.vi

Possible reason(s):

LabVIEW:  Another application is already streaming data to an endpoint in the context you specified. If you specified a context name in the reader name or writer name terminal of the endpoint, you must specify an unused context name. If you did not specify a context name, you must specify an unused context name by entering an endpoint URL in the reader name or writer name terminal.

Share this post


Link to post
Share on other sites
49 minutes ago, parsec said:

I have tried this but I still can't get it to work. I am creating two random strings, so the reader name on the Crio is //localhost:random1/random2

To be clear this should be on the desktop side.

That is,

cRIO: reader <id1-N> writer not selected

app1: writer //localhost:<random2>/<random3>

reader //<crio>/<id1>

app2: writer //localhost:<random4>/<random5>

reader //<crio>/<id2>

etc..

It sounds like you made all contexts unique anyway but that should work. 

Edited by smithd

Share this post


Link to post
Share on other sites

For whatever it's worth, we haven't even been able to get multiple executables that use network streams, each talking to a separate cRIO, to run in parallel. Only the first one connects, and the rest don't. Coworkers investigated this before I joined the company and finally gave up; I haven't dug into it further. Instead we build a single executable that launches all the separate user interfaces, which is slightly annoying since a rebuild of any one interface requires rebuilding all of them, but it works. We recently replaced network streams with TCP communication, for other reasons, but one side effect is that we no longer have this issue.

Since we're seeing this problem even when each user interface talks to a different cRIO, I don't think any amount of changing the endpoint names will fix your problem. Seems like there's some lower-level issue with access to network streams.

Share this post


Link to post
Share on other sites
9 hours ago, parsec said:

I haven't had much success with any of these approaches.  I have made a project encapsulating all of the relevant VIs and targets to make it more clear what I am trying to do.

I don't have 2016 installed so, unfortunately, I am unable to open the code. I'm trying to understand this as I am using network streams in 1:1 and 1:N. Is the attached what you're trying to do (LV 2015)?

 

NetworkStream.zip

Share this post


Link to post
Share on other sites
12 hours ago, parsec said:

I haven't had much success with any of these approaches.  I have made a project encapsulating all of the relevant VIs and targets to make it more clear what I am trying to do.

Network Streams Project.zip

Network Streams Project.zip

While your writer names are unique in testingendpoints.vi, that's the wrong thing to make unique. They are all using the same default context. Check section two and Smithd's context suggestion.

As for rt stream listener.vi, you'll only be able to have one app connect at a time. If you want multiple apps to connect, each needs their own reader name (endpoint1,endpoint2, etc)

Edited by infinitenothing

Share this post


Link to post
Share on other sites
2 hours ago, Tim_S said:

I don't have 2016 installed so, unfortunately, I am unable to open the code. I'm trying to understand this as I am using network streams in 1:1 and 1:N. Is the attached what you're trying to do (LV 2015)?

 

NetworkStream.zip

Those appear to be shared variables, not network streams.

Share this post


Link to post
Share on other sites
32 minutes ago, infinitenothing said:

Those appear to be shared variables, not network streams.

Yea.... ignore me as I seem to be high on whiteout or something.

Share this post


Link to post
Share on other sites
6 hours ago, ned said:

For whatever it's worth, we haven't even been able to get multiple executables that use network streams, each talking to a separate cRIO, to run in parallel. Only the first one connects, and the rest don't. Coworkers investigated this before I joined the company and finally gave up; I haven't dug into it further. Instead we build a single executable that launches all the separate user interfaces, which is slightly annoying since a rebuild of any one interface requires rebuilding all of them, but it works. We recently replaced network streams with TCP communication, for other reasons, but one side effect is that we no longer have this issue.

Since we're seeing this problem even when each user interface talks to a different cRIO, I don't think any amount of changing the endpoint names will fix your problem. Seems like there's some lower-level issue with access to network streams.

I suspected as much. I think I have tried every combination of endpoint and context names possible with no success. I will probably have to change to TCP but it is a huge overhaul.

I have even tried the following scenario:

Crio has two stream readers listening with unique context and endpoint names.

Two executables are made, each with hardcoded context and endpoint names to connect to one or the other stream reader on the Crio.

Each executable successfully connects to its assigned stream reader on the Crio independently.

Both executables running simultaneously fail to connect to the Crio readers.

Share this post


Link to post
Share on other sites
2 hours ago, infinitenothing said:

While your writer names are unique in testingendpoints.vi, that's the wrong thing to make unique. They are all using the same default context. Check section two and Smithd's context suggestion.

As for rt stream listener.vi, you'll only be able to have one app connect at a time. If you want multiple apps to connect, each needs their own reader name (endpoint1,endpoint2, etc)

I have tried unique context names on both ends. The code I shared is one of many attempts at different combinations of context and endpoints names. In one attempt I used the shared variable to send back a set of (random) unique context and endpoint names to the writer, but I had no success this way either. I have engaged NI support so i'll be interested to see if they can make it work. I want them to specifically make it work on a Rio as I don't trust that what works to a dev/executable target on windows will necessarily work on a Rio. From what I can see, the former is somewhat trivial, and the latter not so much.

Incidentally, have you guys actually had this working before? (Multiple executables to single Rio)? I'm wondering whether your suggestions are from experience or whether you are extending the methodology for getting multiple executables to a single windows/dev target working to my situation.

Share this post


Link to post
Share on other sites

Yeah, works fine once you figure out the right parts. Here's example code. You'll want to run one exe with the boolean true and the other with it set false.

RT_BD.png

Host_BD.png

Share this post


Link to post
Share on other sites
3 minutes ago, infinitenothing said:

Yeah, works fine once you figure out the right parts. Here's example code. You'll want to run one exe with the boolean true and the other with it set false.

 

I have data flowing in the opposite direction. I start the Rio up with readers and then the exe clients up as writers. I wonder if this makes a difference? I have effectively tried this methodology before, but I will attempt it again copying exactly what you have done.

Share this post


Link to post
Share on other sites

Doing a replace on the endpoints making the readers to writers and vice versa (no rewiring) made no difference for me. It all works fine.

Share this post


Link to post
Share on other sites
On 5/9/2017 at 5:41 PM, smithd said:

To be clear this should be on the desktop side.

That is,

cRIO: reader <id1-N> writer not selected

app1: writer //localhost:<random2>/<random3>

reader //<crio>/<id1>

app2: writer //localhost:<random4>/<random5>

reader //<crio>/<id2>

etc..

It sounds like you made all contexts unique anyway but that should work. 

I just had NI support get back to me with a working set of VIs. It seems that this is indeed correct. I see that infinitenothing's solution should also work.

I tried the above before but did not manage to get it to work. I suspect I made a mistake somewhere.

The following seems to work;

Assign the Crio listener the following reader name: arbitrary/random1

Leave its writer url empty.

Push the reader name to the shared variable.

Read the shared variable on the host. 

The host reader url should be //CRio-IP/(reader listener name sourced from shared variable, ie arbitrary/random1)

The host writer name must be set to //localhost:random2/random3

I'll implement this in my code now. Let me know if you would like me to share the NI project. They made a rather clean demonstration of how to make it all work for me.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.