Interacting with a Running Simulation¶
Starting in HELICS 2.4 there is a webserver that can be run with the helics_broker or helics_broker_server.
This requires using a boost version >=1.70.
The Webserver can be disabled by the HELICS_DISABLE_BOOST=ON
or HELICS_DISABLE_WEBSERVER=ON
options being set.
Startup¶
The webserver can be started with the option --http
to start a restful interface using HTTP, or --web
to start a server using websockets.
For example to run a broker server with zmq and the webserver active for 30 minutes, you can use the following:
helics_broker_server --http --zmq --duration 30minutes
The --duration
is optional and the default is 30 minutes but any time can be specified.
The web server is configured by default on the localhost address port 43542 to prevent interference with the helics runner or other tools running on standard ports. If you want to configure this it can be done through a configuration file. The format is json.
{
"http": {
"port": 8080,
"interface": "0.0.0.0"
},
"websocket": {
"port": 8008,
"interface": "0.0.0.0"
}
}
Then it can be specified on the command line like so:
$ helics_broker_server --web --zmq --config broker_server_config.json
The configuration will then make the REST web server accessible on any interface on port 8080 and a WebSocket server on port 8080. The port in use can be specified in a configuration file, or via command line such as
$ helics_broker_server --web --zmq --http_server_args="--http_port=80"
Arguments are passed to servers using an option in the form --<server>_server_args
, and in that arg field --<server>_port
and --<server>_interface
are valid arguments. Valid server names are http
, websocket
, zmq
, ‘tcp’, and udp
, and eventually mpi
. The http web server also acknowledges HELICS_HTTP_PORT
as an environment variable. The websocket server acknowledges HELICS_WEBSOCKET_PORT
for the port numbers of the respective servers.
By default the webserver only listens for connections on the localhost network interface, this can be modified by specifying the external address directly or by declaring --external
in the arguments.
$ helics_broker_server --web --zmq --http_server_args="--http_port=8080 --external"
REST API¶
The running webserver will start a process that can respond to HTTP requests.
HTTP actions¶
HTTP VERB |
Description |
---|---|
|
Make a query, usually with nothing in the message body |
|
most general command, usually for creating a broker, but other actions are possible |
|
make a query mostly with data in the body |
|
create a broker |
|
remove a broker |
Parameters¶
parameter |
Description |
---|---|
|
specify the command to use if not implied from the HTTP action, primarily PUSH |
|
The broker to target a focused request, or the name of a broker to create or delete |
|
For commands that create a broker, this is the type of the broker to create |
|
The actual object to target in a query |
|
The query to execute on the specified target |
|
The command line args to pass into a created broker |
Valid commands for the command
parameter in either JSON or the URI:
query
,search
: run a querycreate
: create a brokerdelete
,remove
: remove a broker
Websocket API¶
The websocket API will always respond in a JSON packet. For search/get operations where the response is a JSON value that JSON will be returned. for other responses, they are converted to a JSON.
For create/delete commands the response will be:
{
"status": 0
}
{
"status": 0,
"value": "<query result>"
}
For queries that are not a json value the response will be:
{
"status": 401,
"error": "error message"
}
For queries that did not result in a valid response the response will be:
{
"status": 404,
"error": "error message"
}
The status code corresponds to the most appropriate html error codes.
Making queries¶
As a demo case there is a brokerServerTestCase
executable that can be built when compiling the main HELICS library from source.
Running this example starts a webserver on the localhost using port 80.
The response to queries is a string either in plain text or json. For example:
localhost/brokers
will return
{
"brokers": [
{
"address": "tcp://127.0.0.1:23408",
"isConnected": true,
"isOpen": false,
"isRoot": true,
"name": "brokerA"
},
{
"address": "tcp://127.0.0.1:23410",
"isConnected": true,
"isOpen": true,
"isRoot": true,
"name": "brokerB"
}
]
}
Other queries should be directed to a specific broker such as:
http://localhost/brokerA/brokers
which will produce a string vector:
[41888-wfQ8t-GIGjS-dndI3-e7zuk;41888-e9KF2-HAfm8-Rft0w-JLV4a]
The following:
http://localhost/brokerA/federate_map
will produce a map of the federates in the federation:
{
"brokers": [],
"cores": [
{
"federates": [
{
"id": 131072,
"name": "fedA_1",
"parent": 1879048192
}
],
"id": 1879048192,
"name": "41888-wfQ8t-GIGjS-dndI3-e7zuk",
"parent": 1
},
{
"federates": [
{
"id": 131073,
"name": "fedA_2",
"parent": 1879048193
}
],
"id": 1879048193,
"name": "41888-e9KF2-HAfm8-Rft0w-JLV4a",
"parent": 1
}
],
"id": 1,
"name": "brokerA"
}
Making an invalid query will produce:
http://localhost/brokerA/i_dont_care
-> #invalid
Queries can be make in a number of different formats, the following are equivalent:
http://localhost/brokerA/publications
http://localhost/brokerA
http://localhost/brokerA?query=publications
http://localhost/brokerA/publications
http://localhost/brokerA/root/publications
http://localhost?broker=brokerA&query=publications&target=root
In the example, these will all produce [pub1;fedA_1/pub_string]
which is a list of the publications.
POST requests can also be made using a similar format.
Queries¶
Currently any query is accessible through this interface. Queries have a target and a query. The target is some named object in the federation and the query is a question. The available queries are listed here. More are expected to be added.
Json¶
For both the websockets and REST API they can accept arguments in JSON format. For the REST API the parameters can be a combination of arguments in the URI and JSON in the body of the request For example:
{
"command": "search",
"broker": "broker1",
"target": "federate0",
"query": "current_state"
}
The most likely use case for this will be as a component for a more sophisticated control interface, so a more user friendly setup will be using the webserver as a back-end for control, debugging, information, and visualization of a running co-simulation.