question

Axel Kohonen avatar image
3 Likes"
Axel Kohonen asked Jacob Gillespie commented

Is it possible to use the Server Sent Events with the Http interface in FlexSim?

Hi,

I am investigating the possibilities of using the http interface that FlexSim provides to integrate to an external control system that gives FlexSim orders about where to place items in the model. To accomplish this I need two-way communication between FlexSim and the control system. When new items arrive I need to ask the control system where to place the items, but the control system might also tell FlexSim at any time to reorder the items. The control system will most probably be located on a web server so I was looking at using the http interface.

I can implement the two-way communication by having the client to regularly poll the server for new messages, but this increases the overhead. Another option could be to use the server sent events that use the the http protocol, but I am not sure if it works with FlexSim.

Do you know if it is possible to use the server sent events with the http interface (applicationcommand("sendhttprequest")) in FlexSim? If it is has anyone used it and has some example on how it is done and what changes need to be made at the server and client end of the communication?

Also, is it possible to listen for incoming Http messages e.g. in process flow? Else, I guess polling the server is the only option.

Thank you!

Kind regards,

Axel

FlexSim 16.2.0
webserverhttpweb communicationserver sent events
· 2
5 |100000

Up to 12 attachments (including images) can be used with a maximum of 23.8 MiB each and 47.7 MiB total.

Matthew Gillespie avatar image Matthew Gillespie ♦♦ commented ·
0 Likes 0 ·
Axel Kohonen avatar image Axel Kohonen commented ·

Hi @Matthew Gillespie and @jacob.gillespie

A few other ideas.

1. Another way that could possible to use for server to client messages is long-polling, but I have understood that it needs some modifications to the standard http so I do not know if this can be used with FlexSim either.

2. If possible, another idea to implement the two-way communication could be to run FlexSim and the other end of the communication both as client and server. Is this feasible in any way?

Thanks!

Axel

0 Likes 0 ·
Phil BoBo avatar image
5 Likes"
Phil BoBo answered Phil BoBo commented

Your statement "the http interface in FlexSim" is very vague.

If you are using applicationcommand("sendhttprequest"), then FlexSim is sending synchronous http requests directly with the WinHttp API.

The other internet technologies you have mentioned (server-sent events and long-polling) assume that the client machine is rendering an HTML page and executing Javascript.

You can do that in FlexSim, but you don't use applicationcommand("sendhttprequest").

Instead, you use an HTML widget in a Custom GUI. Within the HTML widget, you can write custom HTML and Javascript code that interacts with a server on the internet.

This is how the Start Page works.

You can use the fireFlexsimEvent() function in JavaScript to execute FlexScript that affects your model. You can use the callwebscriptmethod() command in FlexScript to execute a JavaScript function in your HTML page.

From an HTML widget, you can then both interact with a server on the internet and interact with your model using whatever web technologies are supported by the server you are interacting with and the Webkit library that FlexSim uses to render HTML pages and execute Javascript. (I don't know specifically what internet technologies, such as server-sent events, long polling, ajax, etc, work with Webkit. Your best best to find out whether a certain technology works is to imeplement it within a regular webpage using a web browser such as Chrome or Firefox, then port that HTML/Javascript code into an HTML Widget in FlexSim and see if it still works.)

Webkit probably supports server-sent events, so this is probably easily doable in FlexSim by using an HTML widget (although I haven't tested it to know for sure whether this works). Here is a link to a simple example of writing client-side JavaScript and server-side php code that interacts with server-sent events.

The FlexSim Webserver is an application that performs the work of a web server (hence its name). It is used server-side (as opposed to client-side) to facilitate receiving HTTP requests, passing them on to FlexSim, receiving an HTML response from FlexSim, and then sending that HTML response over the internet back to the client, such as a web browser on someone's computer or another application that communicates via HTTP.

You could use the FlexSim Webserver to spawn an instance of FlexSim, which uses applicationcommand("sendhttprequest") to communicate with an external server, and the external server sends http requests back to the FlexSim Webserver that passes them on to FlexSim. This creates 2 synchronous communication paths where both sides are servers communicating with each other. This is probably not a very good solution for what you are trying to do; polling would be a better solution than this.

The final option is to make a custom C++ DLL that uses whatever internet technology you want to communicate, such as WebSockets. I haven't personally used it, but apparently libwebsockets is a lightweight pure C library that implements WebSockets, which provides full-duplex communication channels over a single TCP connection.

· 8
5 |100000

Up to 12 attachments (including images) can be used with a maximum of 23.8 MiB each and 47.7 MiB total.

Phil BoBo avatar image Phil BoBo ♦♦ commented ·

Here is a live webpage that sends and receives server-sent events: http://tiny-chat.herokuapp.com/

Attached is a FlexSim model where that site is loaded in an HTML widget that has been assigned to the Model Control GUI button.

If you open that model and go to that link in a web browser, you can send chat messages, and the response will be pushed to the other client by the server using server-sent events.

So this shows that it can be done; you just need to implement it on your server and subscribe to it using Javascript in an HTML widget in FlexSim.

1 Like 1 ·
Axel Kohonen avatar image Axel Kohonen Phil BoBo ♦♦ commented ·

Hi @phil

So do I understand it correctly that all the actual server-sent events code is on the webpage (http://tiny-chat.herokuapp.com/) and FlexSim only opens a browser window to view the page?

So if one can produce the same type of code as what is behind the webpage then I only need to use a HTML widget in FlexSim and no custom coding? And can I get the data from the widget to control the model somehow?

Axel

0 Likes 0 ·
Phil BoBo avatar image Phil BoBo ♦♦ Axel Kohonen commented ·

The server-sent event code is both on the client and the server in that tiny-chat app. The client has JavaScript that subscribes to server-sent events on the server. The server has code that handles sending responses to any active sessions that are subscribing to its events.

"So if one can produce the same type of code as what is behind the webpage then I only need to use a HTML widget in FlexSim and no custom coding?"

This question doesn't make sense. "Producing the same type of code" is "custom coding." Using an HTML widget in FlexSim enables you to write custom JavaScript code in FlexSim. You'll need to write the code that is required to do whatever you want to do.

You can get data from the widget to the model by calling the fireFlexsimEvent() function from JavaScript.

You can get data from the model to your HTML page's Javascript using the callwebscriptmethod() command in FlexScript.

1 Like 1 ·
Show more comments
Phil BoBo avatar image Phil BoBo ♦♦ commented ·

I suspect that long-polling with AJAX would also work fine from a Webkit HTML widget in FlexSim.

Here's a link to a page that discusses these various internet communication methods: http://stackoverflow.com/questions/11077857/what-are-long-polling-websockets-server-sent-events-sse-and-comet

1 Like 1 ·
Axel Kohonen avatar image Axel Kohonen Phil BoBo ♦♦ commented ·

Thank you! Will choose the actual implementation method depending on the technology that out client prefers.

0 Likes 0 ·
Axel Kohonen avatar image Axel Kohonen commented ·

Hi @phil.bobo

Thank you for the thorough explanation! Sorry for being vague about what I meant. I was not aware that you were able to use http with FlexSim also with the html widgets and the other ways that you pointed out.

0 Likes 0 ·
Jacob Gillespie avatar image
2 Likes"
Jacob Gillespie answered Jacob Gillespie commented

Server sent events are unfortunately not supported by the FlexSim Webserver. For now your only option is to use a polling strategy like you described.

I am currently working on a new version of the FlexSim Webserver which will be written using node.js and will support using WebSockets. This will allow us true two way communication.

· 2
5 |100000

Up to 12 attachments (including images) can be used with a maximum of 23.8 MiB each and 47.7 MiB total.

Axel Kohonen avatar image Axel Kohonen commented ·

HI @jacob.gillespie

Thank you! Good to hear that you are developing it. Do you have any estimate on when you will have the WebSockets implemented?

Axel

0 Likes 0 ·
Jacob Gillespie avatar image Jacob Gillespie ♦ Axel Kohonen commented ·

The node.js based FlexSim Webserver is now on the downloads page at the bottom:

https://www.flexsim.com/account/#/downloads

(It's only compatible with FlexSim 17.1 and above)

1 Like 1 ·
Matt Long avatar image
2 Likes"
Matt Long answered Axel Kohonen commented

The Webserver allows you to execute nodes and create custom query handlers for communicating with FlexSim. I realize it's kind of hidden inside the User Manual, so here it is pulled out from the Webserver Concepts page:

A list of default queries is available at MAIN:/project/exec/globals/serverinterface/queryhandlers. Using these as templates you can create your own custom query handlers by adding subnodes to the MODEL:/Tools/serverinterface/queryhandlers node. These queryhandler nodes should be toggled flexscript. The name of the node corresponds to a value passed in by the query. For example, webserver.dll?queryinstance=Test%20Model&instancenum=1&reset executes the queryhandler located at MAIN:/project/exec/globals/serverinterface/queryhandlers/reset. Parameters may be added to the query to pass additional information. For example, webserver.dll?queryinstance=Test%20Model&instancenum=1&customquery=1&count=5.

Custom functionality and custom query types for querying the model can also be written for a model by making a flexscript node at MODEL:/Tools/serverinterface/sendreply. This node must call webcommand("httpsendreply", replynode); once to send a reply to the query. This will send a reply in different forms, depending on the type of data in the node given as a parameter. If the node has string data containing a syntactically correct HTTP reply with HTTP headers as defined by http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html, then it will be sent as-is, giving developers full access to send any type of HTTP reply desired. Refer to the code in MAIN:/project/exec/globals/serverinterface/sendreply for an example, which can be copied and edited as needed. Remember that the defaultPage and getRunState queries are used by the job interface.

There's also a short section on how to create your own default page:

The default webpage for a model is generated by using a template found in the tree at MAIN:/project/exec/globals/serverinterface/pagetemplates/default. An html page can be made for a specific model by putting the html into a node created at MODEL:/Tools/serverinterface/defaultpagetemplate. This page can include the php-like <?flexscript ?> tags to generate dynamic material. This will override the default page of the model.

As it says, take a look at the query handlers that are implemented by FlexSim and use those as templates to create your own for passing in custom data. Hopefully this helps.

· 1
5 |100000

Up to 12 attachments (including images) can be used with a maximum of 23.8 MiB each and 47.7 MiB total.

Axel Kohonen avatar image Axel Kohonen commented ·

Hi @Matt

Thank you for the input! I had read this, but always good with a bit more clarification.

The above only applies to when using the FlexSim webserver right? And if you want FlexSim to be a client you can check for hints here, but not really use the code otherwise?

Axel

0 Likes 0 ·