This documentation is mainly for code documentation, especially to extent the server for your needs. However this main page will also give some hints how to use the server.
For hints how to install the server please have a look the INSTALL.MD documentation. This also explains the requirements to use the ISAAC server.
After building the ISAAC server you should have an "isaac" binary, which you can run with –help to get an overview of the possible options:
$ ./isaac --help ISAAC - In Situ Animation of Accelerated Computations 1.0 Usage: isaac [--help] [--web_port <X>] [--sim_port <X>] [--url <X>] [--name <X>] [--jpeg] [--version] --help: Shows this help --web_port: Set port for the websocket clients to connect. Default 2459 --tcp_port: Set port for the tcp clients to connect. Default 2458 --sim_port: Set port for the simulations to connect to. Default 2460 --url: Set the url to connect to from outside. Default 127.0.0.1 --name: Set the name of the server. --version: Shows the version --twitch: Set twitch apikey for twitch live streaming --twitch_url: Set twitch rtmp-url for ssh forwarding or another rtmp service --twitch_bitrate: Set twitch bitrate. Default 400
Option | Comments |
---|---|
--help | Shows the help above |
--web_port --tcp_port --sim_port | The server listens on three ports for incoming connections. The port given by web_port is the port the a websocket (html5) client is using. The tcp_port can be used for a future client using tcp instead of websockets. You can connect via telnet to this port and getting and sending json messages yourself "by hand". The sim_port is the port the simulation tries to connect to. It makes sense to change the default values if you need to run more than more instance of isaac on the same server for some reasons. |
--url | The url, which is broadcastet for some kind of streams to the clients. So this should be an url, which resolves to the computer the server is running on. |
--name | The name of the server, which is broadcastet to clients, too. |
--version | Returns the version of ISAAC. |
--twitch | Activates streaming to an RTMP service. The Twitch™ url is default and it was first introduced for Twitch™, but it does also work with other RTMP services like Youtube™. You need to pass your session/api key after this command! |
--twitch_url | To use another RTMP service than Twitch™ or a more close Twitch™ server you can specify another one here. For Youtube™ you would e.g. use –twitch_url a.rtmp.youtube.com/live2. |
--twitch_bitrate | At default only a bitrate around 400 KBit/s is used, which is around the upstream speed of a 16 MBit DSL connection. However on high performance clusters the upstream is normally much higher, so a value around 2000 - or even more - creates way better streams. |
This section is interesting for people, who want to add a new streaming possibility to ISAAC or another way of connecting for clients.
At the moment it is possible for websockets or pure tcp sockets to connect to the ISAAC Server. If you need another way of communicating, you just need to implement the abstract class MetaDataConnector. You need to overwrite three methods:
MetaDataConnector::init gets a port as parameter. If your connector is not network based you can ignore this parameter. This function is called once at the beginning in the isaac.cpp. However you need to add your connector in this file yourself, so that the server is able to connect to your class.
MetaDataConnector::run is run as own thread in the background right after the init of the class. It is your tasks to wait for messages for connecting clients and to send them to them, but also to tell the ISAAC Server about new connections and incoming messages from them.
MetaDataConnector::getName just needs to return a std::string
with the name of the connector.
MetaDataConnector inherits from MessageAble<MessageContainer> to be able to send and receive interprocess messages to and from the main thread (called Broker). It defines four methods, but you have to only use these:
However at the moment, the server does not react to messages from a MetaDataConnector, so in fact only MessageAble<MessageContainer>::clientGetMessage is important for you. The run method needs to check for new messages from the server with clientGetMessage
all the time. A MessageContainer is returned. This container has 3 attributs
json_t*
. This is a Jansson object. Have a look at the awesome Jansson documentation for details how to access the json data. At the moment the only important message type for you is FORCE_EXIT
, which means you need to exit your run method. After parsing the message you have to delete the object!
If you got a connection from a client you need to tell the ISAAC Broker to add a new client with broker->addDataClient()
. You need to store the returned MetaDataClient* object yourself and to couple it with the just established client connection. Later if messages from the client arrive or you need to send messages to it, you need to use client->clientGetMessage()
and client->clientSendMessage( … )
which work the very same as your own clientSendMessage
and clientGetMessage methods
- they even use the same MessageContainer object. To create a new MessageContainer object to send it to the server just call the constructor with the three above mentioned attributes as parameters. The json_t*
object you need to create yourself with the Jansson API. If you received and forwarded a message to a connected client it is your task to delete the MessageContainer* object!
For a deeper insight have a look at the implementations of TCPDataConnector.cpp and WebSocketDataConnector.cpp.
This works quite the same as with the meta data connector, but you need to inherit from ImageConnector and instead of the MessageContainer a ImageBufferContainer is sent to and from your class. You still need to overwrite an init
, run
and getName
method. However the init
method now has two parameters min_port
and max_port
, which define the range, in which you may open connections to send data. Furthermore there is a new attribute ImageConnector::showClient, which tells ISAAC, whether a client should be told about your connector or not. The Twitch™ plugin uses this, as always the first connected visualization is broadcastet to an RTMP server - independent, what stream the client chose. You still need to add your class to isaac.cpp yourself.
The attributes of ImageBufferContainer are
json_t*
objects, which contain the general meta data for the image, but also the image self as base64 string in payload
. Do not change these without the mutexes below! json_t*
objects above. URIImageConnector uses this to add the image directly to the meta data package instead of streaming it on an extra channel. But you could also add some extra meta data of your stream or only extract meta data from the image and add it to the json object instead of creating a stream at all. The sky's the limit! There are also some differences in the behaviour (besides the other container). You do not establish a client specific connection yourself, but get told from the server with message->type == GROUP_OBSERVED
, that a client chose your stream and wants to see something. If a client stopped observing you get a message from type GROUP_OBSERVED_STOPPED
and if the visualization/simulation stopped you get GROUP_FINISHED
. If you get IMG_FORCE_EXIT
you need to exit your loop. Don't forget to close the streams before.
The most interesting message is surely UPDATE_BUFFER
, which means a new image is available. You can read it directly from the image object with image->buffer
. It is RGBx formated byte-streams, which means 4 bytes are one pixel: the first byte is red, the second blue, the third green and the last one just reserved without useful data. To get the size of the image use ImageBufferContainer::group with message->group->getFramebufferWidth()
and message->group->getFramebufferHeight()
. The image object itself has a reference counter, too. You should not delete the image object at the end, but if you want to start an extra thread for processing the image, it may happen, that the image gets freed in the main thread while you access it. To avoid this you can increase the reference counter yourself with image->incref();
, but afterwards you have to call image->suicide();
in the extra thread processing the image to check the reference counter and to delete the image if it is not in use anymore. Don't call delete image
yourself!
Another important difference to the MetaDataConnector is, that you never delete received messages, but send them back to the Broker with clientSendMessage( message );
. The flow of the ISAAC Server is:
For a deeper insight have a look at the implementations of