11-06-2017 03:30 PM
Hi all,
I have been trying to implement SSE in LabView. I don't know if this is even possible, but it would be really awesome if it was.
So far, this is what I've done in my Web Service project:
And this is my implementation in the client side:
var urlSSE = 'http://127.0.0.1:8001/RIP/SSE';
// Register to the SSE:
var source = new EventSource(urlSSE);
// Manage SSE Events
source.onopen = function(e) {
// Connection was opened.
console.log('Open');
};
source.onmessage = function(e) {
console.log('data:'+e.data);
if (e.id == "CLOSE") {
console.log('Closing');
source.close();
}
};
When I look at the network traffic in my browser's console I can see that the SSE connection is recognized and established:
However, as you can see from above, the SSE only receives the data one time, then the connection ends and, after the timeout (set to 1000 miliseconds in the Vi), the client makes a new connection. This is happening, I guess, because the web service Vi is only executed once per each client request.
What I would like to obtain is a constant flow of data from the LabView server to the client, without having to ask for data from the client. It looks like I'm really close, actually. I would just need to keep the Vi running, particularly the Write Response.vi and the Flush Output.vi. I tried to put those inside a while loop but this didn't work.
Does anyone know how could I do this?
Thanks!
11-06-2017 09:51 PM - edited 11-06-2017 09:52 PM
Hi Ravenink!
That's an awesome start! I played with Server Sent Events in LabVIEW Web Services a while ago and from what I remember it was pretty successful, but I never got around to polishing it up and sharing more broadly.
You can see what I had here: https://github.com/rajsite/i3-sse-server
And a screenshot here: https://twitter.com/rajsite/status/722840800770396160
My memory is a bit fuzzy but I believe in order for it to support more than one request at a time (because you keep the web method VI connection open using a while loop) you had to change a config file setting for max simultaneous connections.
11-07-2017 03:33 AM
Awesome!
I wasn't expecting to find such a helpful response. You are the best 🙂
I'm downloading your code from Github and trying it right now.
11-07-2017 07:14 AM - edited 11-07-2017 07:44 AM
Hi Milan,
I already tried your example. Thanks again for that!
The solution you implemented is basicaly the one I described at the end of my original message: adding the while loop in the Write Response.vi and the Flush Output.vi. It works perfectly fine BUT I have my concerns about it. By adding the while loop, the LabView web server stays inside the loop and never finishes the response request to the web client. Therefore, the web browser never gets to identify the connection as a SSE communication. This happens because the communication is still going and the LabView web server never sends the end of the first message.
The problem with this is that LabView's web service gets caught in the execution of this Vi and it is incapable of doing other things (attending to POST requests, for example). You said I can change the max simultaneous connection to the SSE by modifying the reentrency configuration of the Vi, but what happens if I have a different HTTP Method Vi (for attending POST requests, for example)? Also, is it possible that this solution may affect in some negative way the web client too?
EDIT: I just thought about a possible solution: If you use a for loop instead of a while loop and run it, let's say, 10 or 50 times, you get the end of the SSE (which will then reconnect after the specified timeout) and the web server is therefore free to attend POST requests every once in a while. Still, I just feel like there should be a better way to handle this... Ideas? I tried to set the SSE as one web service (listening in one port) and the POST Method Vi in a different web service (listening in a different port) but it looks like LabView only allows publishing web services in port 8080.
Regards.
10-12-2018 07:07 AM
I've tried to get this to work - but it just hangs until the server or service is stopped. It doesn't appear to be a live connection where events from the service can be sent to the client as I had hoped.
I have had more success using websockets, but this too is not supported by standard LabView and needs to run its own listening service. I was thinking SSE was a better long term solution - not only because I don't really need the duplex nature of websockets, but looking forward to HTTP/2 it would make sense.
10-14-2018 09:42 AM
Hey datid
I finally got this to properly work.
You have and example of a working SSE implementation in my github repository: https://github.com/UNEDLabs/rip-labview-server
10-16-2018 04:15 AM
Thanks for that - I think that is useful not that I fully understand what it is doing...
The tests work ( I had to change a bit that replaced dot with comma, and ther were 2 versions of Request_URL which it didn't appreciate ). I am still not quite sure how I use it - particularly the SSE functionality. There seems to be a lot more in there than that - RIP and JSONrpc - which I don't think I need.
How would you access the eventstream from a browser - for instance ?
Thanks for your help
10-18-2018 08:39 AM
It looks like the problems I have been having getting this to work might well be because of Sophos. It seems Sophos doesn't deal with server sent events in a sensible way - treating them as a download so you only get the data through when the connection closes..
server-sent-events-blocked-by-download-scanner
I haven't fully checked this because I can't turn sophos off !!