DUECA/DUSIME
Loading...
Searching...
No Matches
Public Member Functions | Static Public Attributes | List of all members
dueca::websock::WebSocketsServer< Encoder, Decoder > Class Template Reference

Webserver providing access to DUECA channels. More...

#include <WebSocketsServer.hxx>

Inheritance diagram for dueca::websock::WebSocketsServer< Encoder, Decoder >:
Inheritance graph
[legend]
Collaboration diagram for dueca::websock::WebSocketsServer< Encoder, Decoder >:
Collaboration graph
[legend]

Public Member Functions

 WebSocketsServer (Entity *e, const char *part, const PrioritySpec &ts)
 Constructor.
 
bool complete () final
 Continued construction.
 
template<typename S >
bool _complete (S &server)
 Helper function, templated with the server type.
 
void codeData (std::ostream &s, const DCOReader &r) const final
 Code the data in the reader object.
 
void codeEmpty (std::ostream &s) const final
 Code the data in the reader object.
 
void codeEntryInfo (std::ostream &s, const std::string &w_dataname, unsigned w_entryid, const std::string &r_dataname, unsigned r_entryid) const final
 Code the type information in the reader object.
 
 ~WebSocketsServer ()
 Destructor.
 
- Public Member Functions inherited from dueca::websock::WebSocketsServerBase
 WebSocketsServerBase (Entity *e, const char *part, const PrioritySpec &ts, const char *classname, unsigned char marker)
 Constructor.
 
template<typename S >
bool _complete_http (S &server)
 Helper function, templated with the server type.
 
virtual ~WebSocketsServerBase ()
 Destructor.
 
bool setTimeSpec (const TimeSpec &ts)
 Specify a time specification for the simulation activity.
 
bool checkTiming (const vector< int > &i)
 Request check on the timing.
 
bool setCurrentData (const std::vector< std::string > &i)
 Define a URL for reading latest data.
 
bool setFollowData (const std::vector< std::string > &i)
 Define a URL for following all data in a channel entry.
 
bool setChannelInfo (const std::vector< std::string > &i)
 Define a URL for tracking changes in a channel.
 
bool setWriterSetup (const std::vector< std::string > &i)
 Define a URL for writing to a channel.
 
bool setPresetWriterSetup (const std::vector< std::string > &i)
 Define a URL for writing to a channel.
 
bool setWriteReadSetup (const std::vector< std::string > &i)
 Two-way communication set-up.
 
bool setCertFiles (const std::vector< std::string > &i)
 Set SLL certificates; will convert to use SSL.
 
bool addMimeType (const std::vector< std::string > &i)
 Add a mime type.
 
bool isPrepared () final
 indicate that everything is ready.
 
void startModule (const TimeSpec &time) final
 start responsiveness to input data.
 
void stopModule (const TimeSpec &time) final
 stop responsiveness to input data.
 
void doTransfer (const TimeSpec &ts)
 the method that implements the main calculation.
 
unsigned char getMarker () const
 sending marker, binary or string
 
- Public Member Functions inherited from dueca::Module
virtual ~Module ()
 Destructor.
 
virtual bool isInitialPrepared ()
 To check whether the module is prepared to be prepared.
 
ObjectType getObjectType () const
 The object type within DUECA.
 
virtual void initialStartModule (const TimeSpec &time)
 Initial start opportunity.
 
virtual void finalStopModule (const TimeSpec &time)
 Final stop command.
 
const Entity * getMyEntity ()
 Return a pointer to the entity to which this module belongs.
 
const ModuleStategetState ()
 Return the module state.
 
- Public Member Functions inherited from dueca::NamedObject
const std::string getEntity () const
 Returns the "entity" part of the name.
 
const std::string getClass () const
 Returns the "class" part of the name.
 
const std::string getPart () const
 Returns the sub-entity or "part" part of the name.
 
const NameSetgetNameSet () const
 This returns the complete name set.
 
const GlobalIdgetId () const
 This returns the id.
 

Static Public Attributes

static const char *const classname
 Name of the module.
 

Additional Inherited Members

- Static Public Member Functions inherited from dueca::websock::WebSocketsServerBase
static const ParameterTablegetMyParameterTable ()
 Return the parameter table.
 
- Protected Member Functions inherited from dueca::Module
 Module (const Entity *e, const char *m_class, const char *part)
 Constructor.
 
virtual void setSafetyStop ()
 Put a brake on this module's activities.
 
- Protected Member Functions inherited from dueca::NamedObject
 NamedObject (const GlobalId &id)
 Reserve for AssociateObject.
 
 NamedObject (const NameSet &ns)
 Normal constructor, protected, because it has no use to create a NamedObject by itself.
 
virtual ~NamedObject ()
 Destructor.
 
- Protected Attributes inherited from dueca::websock::WebSocketsServerBase
unsigned char marker
 Marker token for the websocket send calls.
 
boost::scoped_ptr< WsServerserver
 Server, uncoded.
 
boost::scoped_ptr< WssServersserver
 Server, coded.
 
boost::scoped_ptr< HttpServer > http_server
 Http server, uncoded.
 
boost::scoped_ptr< HttpsServer > https_server
 Http Server, coded.
 
std::string server_crt
 Certificate for ssl use, if certificate and key are configured, the ssl version is used.
 
std::string server_key
 Associated key.
 
std::shared_ptr< boost::asio::io_context > runcontext
 IO context to perform a run.
 
unsigned port
 Port to be used.
 
unsigned http_port
 Port for http server.
 
std::string document_root
 Folder with files for http server.
 
std::map< std::string, std::string > mimemap
 Mime types map.
 
bool aggressive_reconnect
 Flag to indicate aggressive reconnection to preset entries.
 
bool immediate_start
 Immediate start, do not wait on DUECA's commands.
 
bool auto_started
 Start flag for immediate_start.
 
StateGuard thelock
 Access lock for shared data.
 
PrioritySpec read_prio
 Priority for reading.
 
TimeSpec time_spec
 Timing specification.
 
bool extended
 If true, use the extended, non-official JSON specification.
 
singleread_t readsingles
 Mapping connecting URL details to an object that reads a specific channel entry.
 
singleread_t autosingles
 Mapping connecting URL details to an object that reads a specific channel entry.
 
singlereadmap_t singlereadsmapped
 Mapping connection id to SingleEntryRead objects.
 
followread_t followers
 Mapping connecting URL details to an object that reads and follows the data in a specific channel entry.
 
followread_t autofollowers
 Mapping connecting URL details to an object that reads and follows the data in a specific channel entry.
 
monitormap_t monitors
 map from URL to monitors
 
writeables_t writersetup
 map from URL to writer setup
 
presetwrites_t presetwriters
 map with preconfigured writeables; these have the channel token created
 
writers_t writers
 map from connection pointers to the actual writers
 
writereadables_t writereadsetup
 map from URL to write/read combination setup
 
writersreaders_t writersreaders
 map with active write/read combinations
 
- Protected Attributes inherited from dueca::Module
ModuleState state
 Flag to remember whether we are stopped due to some error with hardware device manipulation.
 

Detailed Description

template<typename Encoder, typename Decoder>
class dueca::websock::WebSocketsServer< Encoder, Decoder >

Webserver providing access to DUECA channels.

There are two possible variants for this server, "web-sockets-server", which communicates with JSON-coded messages, and "web-sockets-server-msgpack", which uses msgpack (binary) messages for communication.

This server can define a number of URL's:

URL

Description

/configuration

After opening the configuration URL, the client receives a message with all possible configured URL's, in the sections "current", "read", "info", "write" and "write-and-read".

  • current. These endpoints respond to a message from the client and then produce a reply with data. Information in the information section includes:
    • endpoint name
    • dataclass of the DCO object
    • type information of the DCO object
    • entry id (numeric)
  • read. These endpoints will produce messages at the rate of channel writing, or "throttled", when a time specification is given at configuration of the endpoint. Information in the information section includes:
    • endpoint name
    • dataclass
    • type information of the DCO object
    • numeric entry id
  • info. These endpoints provide information on all the entries in a specific channel, and an info endpoint will update when entries are created or deleted. Information only consists of:
    • endpoint name
  • write. These endpoints provide information on entries that can be written to. Information consists of:

    • endpoint
    • dataclass
    • type info

    The latter two are only given if dataclass had been pre-configured. If not given, the dataclass needs to be specified in the first message from a client.

  • write-and-read. These endpoints can be used to establish a two-directional communication on two pre-defined channels. Information consists of

    • endpoint

    The first message upon opening needs to define the dataclass and label. Once bi-directional communication is established, a message is sent with information on both the write direction and read direction.

  • granule. This defines the (floating point) value in seconds of a single integer time increment.

/current/name?entry=..

From a channel labeled "name", reads the current/latest data from the entry given. To get fresh data, write an empty message on the socket (will be discarded). Returns an object with a member "tick", indicating the time tick and single set of data defined in a member "data". If omitted from the URL, the entry id is assumed to be 0. The entry may have been explicitly configured from the start script, and thus its information was provided in the /configuration URL, or it was added by a channelwatcher, and information was provided in an /info/... url (see later).

/read/name?entry=..

From a channel labeled "name", and given entry, open a following read token. Receives all data as it comes in. Data push is provided by the DUECA side. For each new set of data, this returns an array with objects containing time tick and set of data defined. The read entries were either specifically configured (from /configuration), or they are available from information obtained through an info URL.

/info/name

Initiate information gathering for a specific channel. The watching capability (and thereby the url) must have been configured beforehand. For each entry in the channel, this returns an object with the following elements; 'dataclass', for the class of object, 'entry', giving the entry number, 'typeinfo', with an array of type information (see below).

/write/name

Open a write entry for a channel. The data type may be specified in the start script of the module. The first message must be a json object with the member 'label'. Optionally, if this has a member 'ctiming' equal to true, the JSON or msgpack client provides the timing. If this object has a member 'event' equal to false, a stream channel is created; in that case ctiming must be true. If the datatype has not been configured beforehand, this needs to be supplied in the first message.

Optionally a /write/name entry can have been created as preset. In that case, the write token is created at startup of the server, and writing will be immediately available. The write token and channel entry will also persist after a connection is lost, and then a new connection can assume the write entry and continue.

/write-and-read/name

This uses a single bi-directional websocket connection for writing a single entry and reading a corresponding entry in another channel. Information on the data types is provided after completion of the connection. This needs a DUECA module that acts as a server, monitors the channel that is written to from the websocket connection, and creates a matching entry in the reply channel.

The first message from the client must contain a member "dataclass", indicating the DCO type the client wishes to write. An entry in the configured channel is created with this dataclass.

After the server has created a corresponding entry in the reply channel, (having the exact same label), a websocket message is sent back, defining the read and write entry numbers, dataclass and type information. After this, messages can be written, to which the server module should provide replies.

Type information on the members of a dataclass, as returned by the channelinfo URL has the following structure:

key

Description

name

Name of the object's member

type

Type / data class of the object (c++ name)

size (optional)

For fixed size arrays, the size will be given

array (optional)

For array/list types, this value will be True

typeinfo (optional)

If the member is a nested DCO type, the typeinfo will be recursively presented in an array

map (optional)

If the member is a mapped type (e.g. stl map), this value will be true

keytype (optional) If the member is a mapped type (e.g. stl map), this will contain the type / class of the used key

The instructions to create an module of this class from the script are:

dueca.Module('web-sockets-server', <part name; string>, <PrioritySpec>).param(
    set_timing = <TimeSpec>,
    # Supply a time specification to define the update rate of the main activity
    check_timing = <array of integers>,
    # Supply three integer parameters to specify a check on the timing of
    # the main activity: warning limit (in us), critical limit (in us), and
    # the number of loops to test before sending a report (optional, dflt=2000)
    current = <array of strings>,
    # Set up a URL for simply reading the latest data from a single entry
    # in a channel. Specify the URL name, channel name, dataclass, and
    # optionally (in a string) the entry number. Data is returned whenever
    # requested by (an empty) message
    # This results in a URL /current/name?entry=...
    # The returned objects objects have members "tick" for timing and 
    # "data" with the DCO object encoded in JSON or msgpack
    read_timing = <TimeSpec>,
    # Set the read timing for read data. TimeSpec(0,0) disables this
    # again, and will read at the rate the data was sent to the channel.
    extended = <boolean>,
    # Use the extended (sloppy) JSON, with NaN, Infinite and -Infinite.
    # Ensure any external clients understand this format.
    read = <array of strings>,
    # Set up a URL for tracking all data from a single entry in a channel.
    # Specify the URL name, channel name, dataclass, and optionally (in a
    # string) the entry number. Data is pushed to the client, if specified
    # before, the rate given by "read-timing" is used for readingThis results in a URL /read/name?entry=...
    # 
    info = <array of strings>,
    # Set up a URL for obtaining information about channel entries.
    # Specify the URL name and channel name. Any discovered entries will
    # be available in the /current or /read URL'sConfiguring this results in a URL /info/name
    # Information will be provided upon completion of the websocket.
    write = <array of strings>,
    # Set up URL for writing to a channel. Specify URL name, channel name
    # and optionally the dataclass to be written. Any connects will first
    # need to send a JSON object with information for the written entry:
    #   - "dataclass" <string>, needed if not specified in the arguments
    #   - "label" <string>, mandatory
    #   - "ctiming" <bool>, optional for event, mandatory for stream,
    #     indicates that writer will supply timing
    #   - "event", <bool>, optional, default true, event writing
    #   - "stream", <bool>, optional, indicate stream channel
    #   - "bulk", <bool>, optional, send data in bulk priority
    #   - "diffpack", <bool>, optional, use differential pack for sending
    # For stream channels, timing information *must* be supplied. Subsequent
    # messages carry "tick" (if timing supplied, single int for event,
    # two int's for stream), and "data" for the data struct.
    # This results in a URL /write/name, each connection creates an entry
    write_preset = <array of strings>,
    # Set up URL for writing to a channel. Specify URL name, channel name,
    # data class and a label for the channel entry. Optional keywords
    #   - "ctiming" <bool>, optional for event, mandatory for stream,
    #     indicates that writer will supply timing
    #   - "event", <bool>, optional, default true, event writing
    #   - "stream", <bool>, optional, indicate stream channel
    #   - "bulk", <bool>, optional, send data in bulk priority
    #   - "diffpack", <bool>, optional, use differential pack for sending
    # The first JSON message carries the "timing", "event" / "stream"
    # information, this must match the information specified here. This
    # creates a single persistent channel entry, only one client can
    # connect to this entry and write to it. After a disconnect, a new
    # connection can be made. This results in a URL /write/name.
    aggressive_reconnect = <boolean>,
    # Normally a preset entry is only reconnected after the connection with
    # the previous client has been closed. Setting this variable to true
    # makes reconnection more aggressive; old connections are closed and
    # a new connection is always made.
    immediate_start = <boolean>,
    # Start as soon as possible, i.e., when watched channels are valid
    # This is normally only needed for specific debugging purposes.
    write_and_read = <array of strings>,
    # Set up a URL connecting a reading and writing channel set. Specify
    # URL name, channel name for writing, channel name for reading,
    # optionally, add "bulk" for bulk sending mode and "diffpack" for
    # differential packing.
    # The communication is event-based, the first message from the client
    # should have a JSON struct with information on the written dataclass
    # ( { "dataclass": ... } ). The first received message will have
    # information on both dataclasses and channel connections:
    # ( { "write": { "dataclass": ..., "entry": ##, "typeinfo": {...}},
    # (   "read":  { "dataclass": ..., "entry": ##, "typeinfo": {...}}
    # The DUECA module servicing this connection will need to create matching
    # entries to any write created by a connection, using the same label as
    # generated by the socket server.
    # This results in a URL /write-and-read/name, each connection creates a
    # pair of entries, for completion you need a DUECA module monitoring the
    # written channel and submitting an entry in the reading channel with a
    # label matching the written entry
    port = <uint32_t>,
    # Server port to be used, default is 8001.
    http_port = <uint32_t>,
    # If selected by setting a path, http server port, default is 8000.
    document_root = <string>,
    # Location of static files to serve over http; if not supplied, no
    # http server is created.
    # 
    certfiles = <array of strings>,
    # Certificate files for SSL, specify a .crt and a .key file. If these
    # are supplied, wss sockets will be used instead of ws
    add_mimetype = <array of strings>,
    # Add a mime type for an extension, specify the extension (with '.')
    # and the mime type string
    )
'''Description:
JSON/msgpack server providing access to selected channels and channel
entries with websockets.'''

For the configuration of the server, the following options are available.

  1. Manually setting up a /current URL. This specifies a channel entry from a specific channel. Meaningful only for channels with stream data (otherwise you might miss events if reading is not fast enough).

  2. Manually setting up a /read URL. Useful for following events and for obtaining all data written in a channel, e.g. for plotting.

  3. Setting up a /info URL. This can be read to follow changes, and to obtain (initially) the configuration of a channel. With the data one can choose to either open read URL's or current URL's; with an info URL configured, the corresponding read or current URL become available, given that the entries are created.

  4. Setting up a /write URL. The /write URL links the endpoint to the channel name. The first message to such a write URL needs the selection of dataclass, label, and timing control (timing supplied by the websockets side, or added by DUECA on basis of actual time).

  5. Setting up a /write URL with preset/pre-defined entry. In this case, the channel is opened immediately, and a single entry is entered in the channel. This mode is useful if you want the channel entry to be present for the rest of the simulation. If for some reason the websockets connection is broken, a new connection will take its place.

  6. Setting up a /write-and-read URL.

To provide static datafiles (e.g., to start off your javascript program), the module may be configured to act as a very simple web server as well, serving files from a single folder. To get better compatibility with browsers, also configure the mime types for these files.

Constructor & Destructor Documentation

◆ WebSocketsServer()

dueca::websock::WebSocketsServer< Encoder, Decoder >::WebSocketsServer ( Entity * e,
const char * part,
const PrioritySpec & ts )

Constructor.

Is normally called from scheme/the creation script.

Member Function Documentation

◆ complete()

Continued construction.

This is called after all script parameters have been read and filled in, according to the parameter table. Your running environment, e.g. for OpenGL drawing, is also prepared. Any lengty initialisations (like reading the 4 GB of wind tables) should be done here. Return false if something in the parameters is wrong (by the way, it would help if you printed what!) May be deleted.

Reimplemented from dueca::Module.

◆ codeData()

void dueca::websock::WebSocketsServer< Encoder, Decoder >::codeData ( std::ostream & s,
const DCOReader & r ) const
finalvirtual

Code the data in the reader object.

Implements dueca::websock::WebSocketsServerBase.

◆ codeEmpty()

void dueca::websock::WebSocketsServer< Encoder, Decoder >::codeEmpty ( std::ostream & s) const
finalvirtual

Code the data in the reader object.

Implements dueca::websock::WebSocketsServerBase.

◆ codeEntryInfo()

void dueca::websock::WebSocketsServer< Encoder, Decoder >::codeEntryInfo ( std::ostream & s,
const std::string & w_dataname,
unsigned w_entryid,
const std::string & r_dataname,
unsigned r_entryid ) const
finalvirtual

Code the type information in the reader object.

Implements dueca::websock::WebSocketsServerBase.


The documentation for this class was generated from the following file: