mirror of
https://github.com/nasa/trick.git
synced 2024-12-18 20:57:55 +00:00
Merge branch 'master' of github.com:nasa/trick
This commit is contained in:
commit
f20e38f987
@ -43,13 +43,13 @@ void HeaderSearchDirs::AddCompilerBuiltInSearchDirs () {
|
||||
icg_dir << LIBCLANG_MAJOR << "." << LIBCLANG_MINOR ;
|
||||
#ifdef LIBCLANG_PATCHLEVEL
|
||||
icg_dir << "." << LIBCLANG_PATCHLEVEL ;
|
||||
#endif
|
||||
#endif
|
||||
icg_dir << "/include" ;
|
||||
char * resolved_path = realpath(icg_dir.str().c_str(), NULL ) ;
|
||||
if ( resolved_path != NULL ) {
|
||||
hso.AddPath(resolved_path , clang::frontend::System, IsFramework, IsSysRootRelative);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
fp = popen("${TRICK_HOME}/bin/trick-gte TRICK_CXX" , "r") ;
|
||||
|
@ -4,7 +4,7 @@ add_subdirectory(Log)
|
||||
add_subdirectory(EQParse)
|
||||
add_subdirectory(units)
|
||||
|
||||
if( EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/fermi-ware )
|
||||
if( EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/fermi-ware/CMakeLists.txt )
|
||||
add_subdirectory(fermi-ware)
|
||||
endif()
|
||||
|
||||
|
@ -3,6 +3,6 @@ add_subdirectory(DPM)
|
||||
add_subdirectory(DPC)
|
||||
add_subdirectory(DPV/UTILS)
|
||||
add_subdirectory(APPS/GXPLOT)
|
||||
if( EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/../fermi-ware )
|
||||
if( EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/../fermi-ware/CMakeLists.txt )
|
||||
add_subdirectory(APPS/FXPLOT)
|
||||
endif()
|
||||
|
@ -90,3 +90,7 @@ set( TRICKMATH_SRC
|
||||
)
|
||||
|
||||
add_library( trick_math STATIC ${TRICKMATH_SRC})
|
||||
|
||||
if(GSL_FOUND)
|
||||
target_include_directories( trick_math PUBLIC ${GSL_INCLUDE_DIRS} )
|
||||
endif()
|
||||
|
558
trick_source/web/docs/Adding_a_Web_Server_to_Your_Sim.html
Normal file
558
trick_source/web/docs/Adding_a_Web_Server_to_Your_Sim.html
Normal file
File diff suppressed because one or more lines are too long
75
trick_source/web/docs/Adding_a_Web_Server_to_Your_Sim.md
Normal file
75
trick_source/web/docs/Adding_a_Web_Server_to_Your_Sim.md
Normal file
@ -0,0 +1,75 @@
|
||||
# Adding a Web Server to Your Sim
|
||||
|
||||
To add a web server to your simulation, simply include the WebServer sim module into your **S_define** file:
|
||||
|
||||
```
|
||||
#include "sim_objects/WebServer.sm"
|
||||
```
|
||||
|
||||
## Configuration of the Web Server
|
||||
|
||||
The following (input.py) parameters are available to configure your web server:
|
||||
|
||||
|Parameter Name | Default Value| Description |
|
||||
|------------------------|--------------|----------------------------------|
|
||||
|web.server.enable | False |Must be explicitly enabled |
|
||||
|web.server.port | "8888" |Web servers “listen” port |
|
||||
|web.server.document_root| "www" |Web servers document root |
|
||||
|web.server.debug | False |Print Client/Server Communication.|
|
||||
|
||||
For your web server to be active, you must at least specify the following :
|
||||
|
||||
```python
|
||||
web.server.enable = True
|
||||
|
||||
```
|
||||
|
||||
To have your web server listen on port 8890, rather than 8888, you would specify:
|
||||
|
||||
```python
|
||||
web.server.port = "8890"
|
||||
```
|
||||
|
||||
To serve files from a directory called ```my_document_root```, rather than ```www```:
|
||||
|
||||
```python
|
||||
web.server.document_root = "my_document_root"
|
||||
```
|
||||
|
||||
To see client/server communication:
|
||||
|
||||
```python
|
||||
web.server.debug = True
|
||||
```
|
||||
|
||||
## When the Web Server Starts
|
||||
The web server, if enabled, will start during sim initialization. When it does, it will look for the specified document root directory. By default that’s “www”. If root directory doesn’t exist, one will be created with a simple index.html file , a style sheet, and a couple of directories.
|
||||
|
||||
|
||||
## Connecting to Your Web Server
|
||||
Assuming that you accepted the default port, connect to ```http://localhost:8888/``` from your web browser. This will display the index.html file in your root directory.
|
||||
|
||||
|
||||
## The Default Document Root Directory
|
||||
|
||||
The default document root directory that was initially created for you is minimal.
|
||||
|
||||
```
|
||||
www/
|
||||
index.html
|
||||
style.css
|
||||
apps/
|
||||
images/
|
||||
```
|
||||
|
||||
**index.html** is the file that’s displayed when you connect to http://localhost:8888/.
|
||||
|
||||
**style.css** is a CSS style-sheet that’s included by index.html to give it some pizzazz.
|
||||
|
||||
The **apps** directory contains links to some example html/javascript applications
|
||||
in ```$TRICK_HOME/trick_source/web/apps```.
|
||||
|
||||
The **images** directory contains trick_icon.png.
|
||||
|
||||
**You are encouraged to add to, modify, and/or delete these files and directories to best suite the needs of your project.**
|
||||
|
583
trick_source/web/docs/Extending_the_HTTP-API.html
Normal file
583
trick_source/web/docs/Extending_the_HTTP-API.html
Normal file
File diff suppressed because one or more lines are too long
113
trick_source/web/docs/Extending_the_HTTP-API.md
Normal file
113
trick_source/web/docs/Extending_the_HTTP-API.md
Normal file
@ -0,0 +1,113 @@
|
||||
##Extending the HTTP-API
|
||||
|
||||
The HTTP-API is implemented as a collection of ```httpMethodHandlers```. An ```httpMethodHandler``` is a pointer to a function that is expected to respond to an HTTP GET request, using the **Cesanta Mongoose** framework. An ```httpMethodHandler``` is defined (in ```trick/WebServer.hh```) as follows:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
```c
|
||||
typedef void (*httpMethodHandler)(struct mg_connection*, struct http_message*);
|
||||
```
|
||||
|
||||
Documentation for the **Cesanta Mongoose Networking Library** can be found at:
|
||||
[https://cesanta.com/docs/overview/intro.html](https://cesanta.com/docs/overview/intro.html)
|
||||
|
||||
## Example HTTP-API Extension
|
||||
|
||||
Suppose you want your web server to send you a JSON message:
|
||||
|
||||
```json
|
||||
{ "greeting" : "Hello Trick Sim Developer!" }
|
||||
```
|
||||
|
||||
when you invoke the URL: ```http://localhost:8888/api/http/hello```.
|
||||
|
||||
### Creating an ```httpMethodHandler```.
|
||||
|
||||
The following two files will be our implementation of an ```httpMethodHandler```. We'll put these in some models directory ```httpMethods/```.
|
||||
|
||||
**```handle_HTTP_GET_hello.h```**
|
||||
|
||||
```c
|
||||
#ifndef HANDLE_HTTP_GET_HELLO
|
||||
#define HANDLE_HTTP_GET_HELLO
|
||||
|
||||
#ifndef SWIG
|
||||
void handle_HTTP_GET_hello(struct mg_connection *nc, struct http_message *hm);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
```
|
||||
|
||||
**```handle_HTTP_GET_hello.c```**
|
||||
|
||||
```c
|
||||
#include "mongoose/mongoose.h"
|
||||
|
||||
void handle_HTTP_GET_hello(struct mg_connection *nc, struct http_message *hm) {
|
||||
mg_printf(nc, "%s", "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n");
|
||||
const char* json_text =
|
||||
"{ \"greeting\" : \"Hello Trick Sim Developer!\" }";
|
||||
mg_printf_http_chunk(nc, "%s", json_text);
|
||||
mg_send_http_chunk(nc, "", 0);
|
||||
}
|
||||
```
|
||||
|
||||
### Installing our ```httpMethodHandler```.
|
||||
|
||||
We'll do this from our **S_define** file:
|
||||
|
||||
* Add ```(httpMethods/handle_HTTP_GET_hello.c)``` to the ```LIBRARY DEPENDENCIES```.
|
||||
|
||||
* Include our header file:
|
||||
|
||||
```##include "httpMethods/handle_HTTP_GET_hello.h"```
|
||||
|
||||
* In ```create_connections()``` add :
|
||||
|
||||
```c
|
||||
web.server.installHTTPGEThandler( "hello", &handle_HTTP_GET_hello );
|
||||
```
|
||||
### A Complete S_define
|
||||
|
||||
```c++
|
||||
/***********************TRICK HEADER*************************
|
||||
PURPOSE:
|
||||
(Cannon Numeric)
|
||||
LIBRARY DEPENDENCIES:
|
||||
(
|
||||
(cannon/gravity/src/cannon_init.c)
|
||||
(cannon/gravity/src/cannon_numeric.c)
|
||||
(httpMethods/handle_HTTP_GET_hello.c)
|
||||
)
|
||||
*************************************************************/
|
||||
|
||||
#include "sim_objects/default_trick_sys.sm"
|
||||
#include "sim_objects/WebServer.sm"
|
||||
##include "cannon/gravity/include/cannon_numeric.h"
|
||||
##include "httpMethods/handle_HTTP_GET_hello.h"
|
||||
|
||||
class CannonSimObject : public Trick::SimObject {
|
||||
|
||||
public:
|
||||
CANNON cannon ;
|
||||
int foo;
|
||||
CannonSimObject() {
|
||||
("default_data") cannon_default_data( &cannon ) ;
|
||||
("initialization") cannon_init( &cannon ) ;
|
||||
("derivative") cannon_deriv( &cannon ) ;
|
||||
("integration") trick_ret = cannon_integ( &cannon ) ;
|
||||
("dynamic_event") cannon_impact( &cannon) ;
|
||||
}
|
||||
} ;
|
||||
CannonSimObject dyn ;
|
||||
|
||||
IntegLoop dyn_integloop (0.01) dyn;
|
||||
|
||||
void create_connections() {
|
||||
dyn_integloop.getIntegrator(Runge_Kutta_4, 5);
|
||||
web.server.installHTTPGEThandler( "hello", &handle_HTTP_GET_hello );
|
||||
}
|
||||
|
||||
```
|
736
trick_source/web/docs/Extending_the_WS-API.html
Normal file
736
trick_source/web/docs/Extending_the_WS-API.html
Normal file
File diff suppressed because one or more lines are too long
263
trick_source/web/docs/Extending_the_WS-API.md
Normal file
263
trick_source/web/docs/Extending_the_WS-API.md
Normal file
@ -0,0 +1,263 @@
|
||||
#Extending the WebSocket-API
|
||||
|
||||
## When You Create a WebSocket Connection
|
||||
|
||||
Consider the following Javascript, that creates a web socket connection:
|
||||
|
||||
```var ws = new WebSocket('ws://localhost:8888/api/ws/VariableServer');```
|
||||
|
||||
In the URL: ```ws://localhost:8888/api/ws/VariableServer```
|
||||
|
||||
* ```ws://``` specifies the **protocol** (web-socket in this case.)
|
||||
* ```localhost``` specifies the **domain**,
|
||||
* ```:8888``` specifies the **port**, and
|
||||
* ```/api/ws/VariableServer``` specifies the **path**.
|
||||
|
||||
In the Trick web server, the path associated with a websocket must begin with
|
||||
```/api/ws/```. The remaining part of the path, i.e., ```VariableServer``` is the **key** that specifies the **sub-protocol**, prescribing what messages will be passed between client and server, and what those messages mean.
|
||||
|
||||
When a web-socket connection is established, the **key** will determine what type (sub-class) of ```WebSocketSession``` object to create, to manage the connection.
|
||||
|
||||
## WebSocketSession
|
||||
A ```WebSocketSession``` is a pure virtual base class meant to represent the state of one of potentially many websocket connections. It provides methods to:
|
||||
|
||||
1. Synchronously marshall Trick simulation data for out-going messages
|
||||
2. Send messages to the websocket client, and
|
||||
3. Receive and process messages from the websocket client.
|
||||
|
||||
To implement a new websocket sub-protocol, one needs to derive a new class from this base class, and implement the required methods. ```WebSocketSession.hh``` can be found in ```${TRICK_HOME}/include/trick/```.
|
||||
|
||||
### WebSocketSession.hh
|
||||
```c
|
||||
/*************************************************************************
|
||||
PURPOSE: (Represent Websocket connection.)
|
||||
**************************************************************************/
|
||||
#ifndef WEB_SOCKET_SESSION_HH
|
||||
#define WEB_SOCKET_SESSION_HH
|
||||
|
||||
#include <string>
|
||||
#ifndef SWIG
|
||||
#include "mongoose/mongoose.h"
|
||||
#endif
|
||||
|
||||
class WebSocketSession {
|
||||
public:
|
||||
WebSocketSession(struct mg_connection *nc):connection(nc){};
|
||||
virtual ~WebSocketSession() {};
|
||||
virtual void marshallData()=0;
|
||||
virtual void sendMessage()=0;
|
||||
virtual int handleMessage(std::string)=0;
|
||||
|
||||
struct mg_connection* connection;
|
||||
};
|
||||
#endif
|
||||
```
|
||||
|
||||
### Adding Your New WebSocketSession Type to the WebServer
|
||||
|
||||
To install your new websocket protocol, you'll need to create a function that
|
||||
creates an instance of your new WebSocketSession type. Then you'll need to call
|
||||
```HTTP_Server::installWebSocketSessionMaker``` to install the function, with a
|
||||
label.
|
||||
|
||||
The function you'll create will take ```struct mg_connection *``` as an argument
|
||||
and return ```WebSocketSession*```.
|
||||
|
||||
## Example
|
||||
|
||||
Let's create a new web socket protocol that sends the time in GMT or local time.
|
||||
|
||||
First we'll derive a new type called ```TimeSession ``` from ```WebSocketSession```.
|
||||
|
||||
### TimeSession.hh
|
||||
|
||||
```c
|
||||
/*************************************************************************
|
||||
PURPOSE: (Represent the state of a variable server websocket connection.)
|
||||
**************************************************************************/
|
||||
#ifndef TIMESESSION_HH
|
||||
#define TIMESESSION_HH
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "time.h"
|
||||
#include "trick/WebSocketSession.hh"
|
||||
|
||||
class TimeSession : public WebSocketSession {
|
||||
public:
|
||||
enum Zone { GMT, LOCAL};
|
||||
TimeSession(struct mg_connection *nc);
|
||||
~TimeSession();
|
||||
void marshallData();
|
||||
void sendMessage();
|
||||
int handleMessage(std::string);
|
||||
private:
|
||||
time_t now;
|
||||
Zone zone;
|
||||
};
|
||||
|
||||
WebSocketSession* makeTimeSession( struct mg_connection *nc );
|
||||
#endif
|
||||
```
|
||||
|
||||
Below is our implementation. Notice the function ```makeTimeSession``` at the bottom.
|
||||
|
||||
|
||||
### TimeSession.cpp
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <iostream>
|
||||
#include "TimeSession.hh"
|
||||
|
||||
// CONSTRUCTOR
|
||||
TimeSession::TimeSession( struct mg_connection *nc ) : WebSocketSession(nc) {
|
||||
time(&now);
|
||||
}
|
||||
|
||||
// DESTRUCTOR
|
||||
TimeSession::~TimeSession() {}
|
||||
|
||||
void TimeSession::marshallData() {
|
||||
time(&now);
|
||||
}
|
||||
|
||||
void TimeSession::sendMessage() {
|
||||
|
||||
char message[1024];
|
||||
struct tm *theTime;
|
||||
if (zone == TimeSession::LOCAL) {
|
||||
theTime = localtime(&now);
|
||||
} else {
|
||||
theTime = gmtime(&now);
|
||||
}
|
||||
int hours = theTime->tm_hour;
|
||||
int minutes = theTime->tm_min;
|
||||
int seconds = theTime->tm_sec;
|
||||
int day = theTime->tm_mday;
|
||||
int month = theTime->tm_mon + 1;
|
||||
int year = theTime->tm_year + 1900;
|
||||
|
||||
sprintf(message, "Time: %02d:%02d:%02d Date: %02d/%02d/%d\n", hours, minutes, seconds, month, day, year);
|
||||
mg_send_websocket_frame(connection, WEBSOCKET_OP_TEXT, message, strlen(message));
|
||||
}
|
||||
|
||||
int TimeSession::handleMessage(std::string client_msg) {
|
||||
|
||||
if (client_msg.compare("GMT") == 0) {
|
||||
zone = TimeSession::GMT;
|
||||
} else if (client_msg.compare("LOCAL") == 0) {
|
||||
zone = TimeSession::LOCAL;
|
||||
} else {
|
||||
std::cerr << "ERROR: Unknown command \"" << client_msg << "\"." << std::endl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// WebSocketSessionMaker function for a TimeSession.
|
||||
WebSocketSession* makeTimeSession( struct mg_connection *nc ) {
|
||||
std::cerr << "DEBUG: Creating new TimeSession." << std::endl;
|
||||
return new TimeSession(nc);
|
||||
}
|
||||
```
|
||||
|
||||
We put ```TimeSession.cpp``` and ```TimeSession.cpp``` into a models directory called ```httpMethods/```.
|
||||
|
||||
|
||||
### S_define Modifications
|
||||
|
||||
1. Specify the dependency on the ```httpMethods/TimeSession.cpp``` compilation unit.
|
||||
2. We should already be including the WebServer sim object, otherwise we don't even have a webserver.
|
||||
3. We need to include our new header file: ```##include "httpMethods/TimeSession.hh"```
|
||||
4. Finally, install our WebSocketSession type: ```web.server.installWebSocketSessionMaker("Time", &makeTimeSession);```
|
||||
The label we use for our protocol here is "Time", but it can be whatever name you choose.
|
||||
|
||||
```c++
|
||||
/***********************TRICK HEADER*************************
|
||||
PURPOSE:
|
||||
(Cannon Numeric)
|
||||
LIBRARY DEPENDENCIES:
|
||||
(
|
||||
(cannon/gravity/src/cannon_init.c)
|
||||
(cannon/gravity/src/cannon_numeric.c)
|
||||
(httpMethods/TimeSession.cpp) // <--(1)
|
||||
)
|
||||
*************************************************************/
|
||||
|
||||
#include "sim_objects/default_trick_sys.sm"
|
||||
#include "sim_objects/WebServer.sm" // <--(2)
|
||||
##include "cannon/gravity/include/cannon_numeric.h"
|
||||
##include "httpMethods/TimeSession.hh" // <--(3)
|
||||
|
||||
class CannonSimObject : public Trick::SimObject {
|
||||
|
||||
public:
|
||||
CANNON cannon ;
|
||||
int foo;
|
||||
CannonSimObject() {
|
||||
("default_data") cannon_default_data( &cannon ) ;
|
||||
("initialization") cannon_init( &cannon ) ;
|
||||
("derivative") cannon_deriv( &cannon ) ;
|
||||
("integration") trick_ret = cannon_integ( &cannon ) ;
|
||||
("dynamic_event") cannon_impact( &cannon) ;
|
||||
}
|
||||
} ;
|
||||
CannonSimObject dyn ;
|
||||
|
||||
IntegLoop dyn_integloop (0.10) dyn;
|
||||
|
||||
void create_connections() {
|
||||
dyn_integloop.getIntegrator(Runge_Kutta_4, 5);
|
||||
web.server.installWebSocketSessionMaker("Time", &makeTimeSession); // <--(4)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Testing The New WebSocket Interface
|
||||
|
||||
To test your new web socket interface, put the following ```time.html``` file in ```$YOUR_SIM_DIRECTORY/www/apps```. Then request ```http://localhost:8888/apps/time.html``` from your browser. You should see the time messages from your sim.
|
||||
|
||||
### time.html
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>WS Example</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="output"></div>
|
||||
<script type="text/javascript">
|
||||
|
||||
function log(s) {
|
||||
var p = document.createElement("p");
|
||||
p.style.wordWrap = "break-word";
|
||||
p.textContent = s;
|
||||
output.appendChild(p);
|
||||
}
|
||||
|
||||
var ws = new WebSocket('ws://localhost:8888/api/ws/Time');
|
||||
|
||||
// WebSocket Event Handlers
|
||||
ws.onopen = function(e) {
|
||||
ws.send("GMT");
|
||||
};
|
||||
ws.onmessage = function(e) {
|
||||
log(e.data);
|
||||
};
|
||||
ws.onerror = function(e) {
|
||||
console.log("WebSocket Error: " , e);
|
||||
handleErrors(e);
|
||||
};
|
||||
ws.onclose = function(e) {
|
||||
console.log("Connection closed", e);
|
||||
};
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
633
trick_source/web/docs/HTTP-API_alloc_info.html
Normal file
633
trick_source/web/docs/HTTP-API_alloc_info.html
Normal file
File diff suppressed because one or more lines are too long
87
trick_source/web/docs/HTTP-API_alloc_info.md
Normal file
87
trick_source/web/docs/HTTP-API_alloc_info.md
Normal file
@ -0,0 +1,87 @@
|
||||
# HTTP-API: alloc_info
|
||||
|
||||
```http://localhost:8888/api/http/alloc_info```
|
||||
|
||||
## Purpose
|
||||
|
||||
Request a JSON encoded sub-list of allocation descriptors from the Memory Manager’s alloc_info list.
|
||||
|
||||
## Query String Parameters
|
||||
| Parameter|Default|Description |
|
||||
|-------------|----|----------------------------------|
|
||||
| ```start``` | 0 | starting index of the sub-list. |
|
||||
| ```count``` | 20 | number of allocation descriptors.|
|
||||
|
||||
### EXAMPLE:
|
||||
|
||||
```http://localhost:8888/api/http/alloc_info?start=20&count=2```
|
||||
|
||||
## Query Response
|
||||
|
||||
Returns a JSON object containing four name-value pairs:
|
||||
|
||||
### JSON Response Object
|
||||
|
||||
| Name | Value Description |
|
||||
|-------------------|-----------------------------------------|
|
||||
| ```alloc_total``` | Total number allocations in the Memory Manager’s alloc_info list. |
|
||||
| ```chunk_size``` | Number of allocation description objects in ```alloc_list```. |
|
||||
| ```chunk_start``` | The Memory Manager alloc_info index of the first ```alloc_list``` element below|
|
||||
| ```alloc_list``` | Array of JSON Allocation Description objects (described below). |
|
||||
|
||||
|
||||
### JSON Allocation Description Object
|
||||
|
||||
| Name | Value Description |
|
||||
|---------------|---------------------------------------------------------------------------------|
|
||||
| ```name``` | Name of the allocation. May be ```Null``` |
|
||||
| ```start``` | Starting address of the allocation. |
|
||||
| ```end``` | Ending address of the allocation. |
|
||||
| ```num``` | |
|
||||
| ```size``` | Size of the allocation in bytes. |
|
||||
| ```type``` | Type descriptor of the allocation. |
|
||||
| ```stcl``` | Storage class of the allocation. Either ```TRICK_EXTERN``` or ```TRICK_LOCAL```.|
|
||||
| ```language```| Language. Either : ```Language_C``` or ```Language_CPP```. |
|
||||
| ```index``` | Array dimension sizes of the allocation (if it represents an array). |
|
||||
|
||||
|
||||
## Example:
|
||||
|
||||
In ```SIM_cannon_numeric``` (one of Trick's example sims) the following query resulted in the following JSON.
|
||||
|
||||
#### Query
|
||||
|
||||
```http://localhost:8888/api/http/alloc_info?start=20&count=2```
|
||||
|
||||
#### Response
|
||||
|
||||
```json
|
||||
{ "alloc_total":43,
|
||||
"chunk_size":2,
|
||||
"chunk_start":20,
|
||||
"alloc_list":[
|
||||
{ "name":"dyn",
|
||||
"start":"0x101aa9900",
|
||||
"end":"0x101aa9b27",
|
||||
"num":"1",
|
||||
"size":"552",
|
||||
"type":"CannonSimObject",
|
||||
"stcl":"TRICK_EXTERN",
|
||||
"language":"Language_CPP",
|
||||
"index": []
|
||||
}
|
||||
,
|
||||
{ "name":"web",
|
||||
"start":"0x101aa9610",
|
||||
"end":"0x101aa98ff",
|
||||
"num":"1",
|
||||
"size":"752",
|
||||
"type":"WebServerSimObject",
|
||||
"stcl":"TRICK_EXTERN",
|
||||
"language":"Language_CPP",
|
||||
"index": []
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
```
|
659
trick_source/web/docs/WS-API_VariableServer.html
Normal file
659
trick_source/web/docs/WS-API_VariableServer.html
Normal file
File diff suppressed because one or more lines are too long
210
trick_source/web/docs/WS-API_VariableServer.md
Normal file
210
trick_source/web/docs/WS-API_VariableServer.md
Normal file
@ -0,0 +1,210 @@
|
||||
# WS-API: VariableServer
|
||||
|
||||
```ws://localhost:8888/api/ws/VariableServer```
|
||||
|
||||
## Purpose
|
||||
|
||||
JSON Variable Server
|
||||
|
||||
## Client to Server Command Messages
|
||||
|
||||
Add a Trick Variable to the current session.
|
||||
|
||||
```json
|
||||
{ "cmd" : "var_add",
|
||||
"var_name" : string
|
||||
}
|
||||
```
|
||||
Stop sending periodic ```var_list``` messages (*see below*) from the server.
|
||||
|
||||
```json
|
||||
{ "cmd" : "var_pause" }
|
||||
```
|
||||
|
||||
Resume sending periodic ```var_list``` response messages from the server.
|
||||
|
||||
```json
|
||||
{ "cmd" : "var_unpause" }
|
||||
|
||||
```
|
||||
|
||||
Send one ```var_list``` message from the server.
|
||||
|
||||
```json
|
||||
{ "cmd" : "var_send" }
|
||||
```
|
||||
|
||||
Clear all variables from the current session, that is: undo all of the ```var_add``` commands.
|
||||
|
||||
```json
|
||||
{ "cmd" : "var_clear" }
|
||||
```
|
||||
|
||||
Disconnect from the variable server.
|
||||
|
||||
```json
|
||||
{ "cmd" : "var_exit" }
|
||||
```
|
||||
|
||||
Set the period (in milliseconds) at which ```var_list``` messages are sent form the server.
|
||||
|
||||
```json
|
||||
{ "cmd" : "var_cycle",
|
||||
"period" : integer
|
||||
}
|
||||
```
|
||||
|
||||
Execute the given Python code in the host sim.
|
||||
|
||||
```json
|
||||
{ "cmd" : "python",
|
||||
"pycode" : string
|
||||
}
|
||||
```
|
||||
|
||||
Send the sie structure from the server. Response will be the ```sie``` response message (*below*).
|
||||
|
||||
```json
|
||||
{ "cmd" : "sie" }
|
||||
```
|
||||
|
||||
Send the units for the given variable. Response will be the ```units``` response message (*below*).
|
||||
|
||||
```json
|
||||
{ "cmd" : "units",
|
||||
"var_name" : string
|
||||
}
|
||||
```
|
||||
|
||||
## Server to Client Response Messages
|
||||
|
||||
Error Response
|
||||
|
||||
```json
|
||||
{ "msg_type" : "error",
|
||||
"error_text" : string
|
||||
}
|
||||
```
|
||||
|
||||
Periodic response containing the values of variables requested by ```var_add```.
|
||||
|
||||
```json
|
||||
{ "msg_type" : "var_list"
|
||||
"time" : double
|
||||
"values" : []
|
||||
}
|
||||
```
|
||||
|
||||
Response to the ```sie``` command (*above*).
|
||||
|
||||
```json
|
||||
{ "msg_type" : "sie",
|
||||
"data" : string
|
||||
}
|
||||
```
|
||||
|
||||
Response to the ```units``` command (*above*).
|
||||
|
||||
```json
|
||||
{ "msg_type" : "units",
|
||||
"var_name" : string,
|
||||
"data" : string
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Example Variable Server Client
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>WS Experiments</title>
|
||||
</head>
|
||||
<body>
|
||||
<style>
|
||||
table { border-collapse: collapse; width: 100%; }
|
||||
th, td { text-align: left; padding: 8px; }
|
||||
tr:nth-child(even){background-color: #f2f2f2}
|
||||
th { background-color: #562399; color: white; }
|
||||
</style>
|
||||
<header>
|
||||
</header>
|
||||
|
||||
<div class="variableDisplay"></div>
|
||||
<table class="variables">
|
||||
<tr>
|
||||
<th>Variable</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div id="output"></div>
|
||||
<script type="text/javascript">
|
||||
function log(s) {
|
||||
var p = document.createElement("p");
|
||||
p.style.wordWrap = "break-word";
|
||||
p.textContent = s;
|
||||
output.appendChild(p);
|
||||
}
|
||||
function sendMessage(msg) {
|
||||
ws.send(msg);
|
||||
}
|
||||
// Interface to Trick WebSocket Variable Server
|
||||
function setPeriod(period) {
|
||||
sendMessage(`{"cmd":"var_cycle","period":${period}}`);
|
||||
}
|
||||
function addVarTableRow(name, value) {
|
||||
// create a row in the table that contains two <td>s, one for the var_name and one for its value.
|
||||
let tr = document.createElement('tr');
|
||||
let td1 = document.createElement('td');
|
||||
td1.textContent = `${name}`;
|
||||
let td2 = document.createElement('td');
|
||||
td2.textContent = `${value}`;
|
||||
td2.className = "values";
|
||||
tr.appendChild(td1);
|
||||
tr.appendChild(td2);
|
||||
varTable.appendChild(tr);
|
||||
}
|
||||
function addVariable(name, value) {
|
||||
sendMessage(`{"cmd":"var_add","var_name": "${name}"}`);
|
||||
addVarTableRow(name, value);
|
||||
}
|
||||
var varTable = document.querySelector('table.variables');
|
||||
|
||||
|
||||
var ws = new WebSocket('ws://localhost:8888/api/ws/VariableServer');
|
||||
ws.onopen = function(e) {
|
||||
setPeriod(100);
|
||||
addVarTableRow("Time", 0.0);
|
||||
addVariable("dyn.cannon.pos[0]", 0.0);
|
||||
addVariable("dyn.cannon.pos[1]", 0.0);
|
||||
addVariable("dyn.cannon.vel[0]", 0.0);
|
||||
addVariable("dyn.cannon.vel[1]", 0.0);
|
||||
addVariable("dyn.cannon.time", 0.0);
|
||||
addVariable("dyn.cannon.timeRate", 0.0);
|
||||
addVariable("dyn.cannon.impact", 0.0);
|
||||
addVariable("I.dont.exist", 0.0);
|
||||
sendMessage("{\"cmd\":\"var_unpause\"}");
|
||||
};
|
||||
ws.onmessage = function(e) {
|
||||
let msg = JSON.parse(e.data);
|
||||
if (msg.msg_type == "values") {
|
||||
let valueNodes = varTable.getElementsByClassName("values");
|
||||
valueNodes[0].textContent = msg.time;
|
||||
for (let i = 0; i < msg.values.length; i++ ) {
|
||||
valueNodes[i+1].textContent = msg.values[i];
|
||||
}
|
||||
}
|
||||
};
|
||||
ws.onerror = function(e) {
|
||||
console.log("WebSocket Error: " , e);
|
||||
handleErrors(e);
|
||||
};
|
||||
ws.onclose = function(e) {
|
||||
console.log("Connection closed", e);
|
||||
};
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
43
trick_source/web/docs/index.html
Normal file
43
trick_source/web/docs/index.html
Normal file
@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<title>Web Server Documentation</title>
|
||||
<div class="header">
|
||||
<table>
|
||||
<th><img src="trick_icon.png" height="64" width="64"></th>
|
||||
<th><h1>Web Server Documentation</h1></th>
|
||||
</table>
|
||||
</div>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div style="background:#efefef">
|
||||
<ul>
|
||||
<li>
|
||||
<h2>
|
||||
<a href="Adding_a_Web_Server_to_Your_Sim.html">Adding a Web Server to Your Sim</a>
|
||||
</h2></li>
|
||||
|
||||
<li>
|
||||
<h2>Web Server APIs</h2>
|
||||
<ul>
|
||||
<li><a href="HTTP-API_alloc_info.html">HTTP-API: alloc_info</a></li>
|
||||
<li><a href="WS-API_VariableServer.html">WS-API: VariableServer</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<h2>Adding New Web Server APIs</h2>
|
||||
<ul>
|
||||
<li><a href="Extending_the_HTTP-API.html">Extending the HTTP-API</a></li>
|
||||
<li><a href="Extending_the_WS-API.html">Extending the WS-API</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
19
trick_source/web/docs/style.css
Normal file
19
trick_source/web/docs/style.css
Normal file
@ -0,0 +1,19 @@
|
||||
h1 {
|
||||
font-family: fantasy, cursive, serif;
|
||||
font-size: 32px;
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-family: sans-serif;
|
||||
font-size: 18px;
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
a {
|
||||
font-family: sans-serif;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
div.header { background-image: linear-gradient(#afafff, white); }
|
||||
|
BIN
trick_source/web/docs/trick_icon.png
Normal file
BIN
trick_source/web/docs/trick_icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
Loading…
Reference in New Issue
Block a user