Jump to content

Reusable connection process


Recommended Posts

So, i currently have a reusable connection process and you can easily plug in override VIs for open/close/read/write and basically use any connection type you want (UDP, TCP, VISA etc). As it stands now, our process handles multiple connections but if a message is sent out it is sent to all client connections. We are going to be adding some functionality for request-response which will require an outgoing response message to a specific client connection that made the request. I am not sure how to handle the managing of which connection sent the message and needs the response. One idea I had was give each connection an ID, when a request is received, pass the request with the ID to the loop which processes the data, then sends the result back with the ID so the connection process knows where to send it. I could also use the refnum but I don't like the idea of other processes having access to the connection references, even if it's protected by being wrapped in a class, because I have to add in error handling for lost connections outside of the process which already has the code to manage them. 

 

So, I'm curious how people have handled this and if my approach seems reasonable. 

Edited by for(imstuck)
Link to comment

In a somewhat similar situation in the past I did something like a combination of what you mention here, although in my case I was using only TCP connections. I had one loop that handled all TCP communication in both directions. Incoming data was converted to a variant, and then I added the connection refnum as an attribute of that variant. The variant went into a queue, where it could be consumed by another loop. To return a response, that consumer loop enqueued a new variant with the response data and with the same connection refnum as an attribute, so that the communication loop could send it over the correct connection. Making the connection an object obviously adds a layer of safety that I didn't have.

Link to comment
I could also use the refnum but I don't like the idea of other processes having access to the connection references...because I have to add in error handling for lost connections outside of the process which already has the code to manage them. 
Why? You can still have the replies routed back through your connection process. Attach to the original message whatever info is needed to direct the reply.
Link to comment

An ID in the sense you are using it is functionally equivalent to a refnum, assuming behind the scenes you'd be tracking refnum regardless of what you send along for the ride over the transport layer. An ID is a unique number which *your code* dereferences. A refnum is a unique number *LabVIEW* dereferences.

In this case I'd save myself the trouble and not bother with the extra layer of indirection, it gets you nothing in return but does cost you development and run time.

Link to comment

My concern was if I package the TCP refnum in the request message it needs to be taken out of the request message to be packaged in with the response message. That means I'd need a "getter" which I don't want because it would expose the reference itself. I suppose I could wrap the reference up in a class and pass that class holding the reference around, not exposing any methods that allow direct access to the reference itself.

Edited by for(imstuck)
Link to comment
My concern was if I package the TCP refnum in the request message it needs to be taken out of the request message to be packaged in with the response message. That means I'd need a "getter" which I don't want because it would expose the reference itself. I suppose I could wrap the reference up in a class and pass that class holding the reference around, not exposing any methods that allow direct access to the reference itself.
You don't need a getter; you need a Reply method.
  • Like 1
Link to comment
So, i currently have a reusable connection process and you can easily plug in override VIs for open/close/read/write and basically use any connection type you want (UDP, TCP, VISA etc). As it stands now, our process handles multiple connections but if a message is sent out it is sent to all client connections. We are going to be adding some functionality for request-response which will require an outgoing response message to a specific client connection that made the request. I am not sure how to handle the managing of which connection sent the message and needs the response. One idea I had was give each connection an ID, when a request is received, pass the request with the ID to the loop which processes the data, then sends the result back with the ID so the connection process knows where to send it. I could also use the refnum but I don't like the idea of other processes having access to the connection references, even if it's protected by being wrapped in a class, because I have to add in error handling for lost connections outside of the process which already has the code to manage them. 

 

So, I'm curious how people have handled this and if my approach seems reasonable. 

 

Sounds to me like Dispatcher.

Link to comment
  • 2 weeks later...
You don't need a getter; you need a Reply method.

I agree. However, the problem I run into here is I don't want to reply directly to the client. I have a mediator which manages a list of all connections, error handling if a connection has been lost, etc. This mediator exists because my opener, readers, and writers are all separate parallel processes. So, the reply will actually go through the mediator, at which point the mediator should be the one distributing the message to the proper client via this reply method. The only way I can figure to get this safety (force the reply to go through the mediator) is make the mediator a friend of the client, and make the reply method community scope. 

 

Again, I reiterate the reason I want this safety in case it is unclear. If the connection closes, I will get an error because the transport mechanism to the client will no longer exist. So, if I reply to the client directly, any loop that wants to send a reply now has to have error handling for this case. By forcing things to go through a mediator, I can put all this handling in a single location.

Edited by for(imstuck)
Link to comment

I don’t know enough about your architecture to follow the issue.  My “Reply” method is a public method of my message class.  If you looked at the “reply address” of a message received through my TCP client server, you would see that it points to a “TCP Connection actor” spawned to handle specific TCP connection.  As there is one TCP Connection actor for each client connection, this effectively routes replies to the right destination.

 

As for errors in making a reply, let me offer an alternate philosophy: ignore them.  I impose a design constraint that a Request-Reply transaction is the responsibility of the Requestor.  The Replier is responsible for attempting to reply to the address provided, but is not concerned with a failure of that address.  That is outside it’s scope.

Link to comment
The only way I can figure to get this safety (force the reply to go through the mediator) is make the mediator a friend of the client, and make the reply method community scope.

 

How are you exchanging references?  If the only place to get a reference is through the mediator, the mediator can force all references to point back to it, and then relay the message to the proper client.  That way the different parts only know about the mediator and don't have any reference to any other client.  Some more info on architecture might help.

 

As for errors in making a reply, let me offer an alternate philosophy: ignore them.  I impose a design constraint that a Request-Reply transaction is the responsibility of the Requestor.  The Replier is responsible for attempting to reply to the address provided, but is not concerned with a failure of that address.  That is outside it’s scope.

 

Ditto this.  It can be useful to know about these from a debugging point of view, but for final product, I ignore at the replier level.

Link to comment

Join the conversation

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

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
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.