IntroductionPurposeCommon Fields and Methods
Source and Sink Clients
Channel Structures and NamingConstructorsSource API
Connections
Channel Lists
Data TypesDefine Channel ListSink API
Time Stamps
Specify Channel Data
Send Data
Example Source CodeSpecify Channel List
Sink Modes
Get Data
Extract Data
Example Sink Code
The SAPI is implemented as a set of utility methods on top of the full RBNB Java API. Certain concessions are made to optimize portability, such as avoiding the use of overloaded methods.
Whereas this document most directly applies to the Java SAPI, the C/C++, Active X, Java Bean, and other APIs are directly layered on the Java SAPI. Thus, except for minor syntax differences, this documentation is generally applicable for these other APIs as well.
For both Source and Sink clients, data channels are individually identified and "staged" using the AddChannel method prior to being transferred (Fetch or Flush). Behind the scenes, the SAPI incrementally builds up the corresponding RMap data structures.
Multi-tiered hierarchical channel structures can be created, requested, and referenced through a simple directory-like naming convention. A fully specified channel name consists of three main parts:
Server/Source/ChannelWhere:
Server: serverName assigned at Server startup (command line argument)Data Sources define channels (AddChannel) with the Server and Source parts implied. The channel name part may itself be multi-tiered, such as:
Source: clientName given by Source via OpenRBNBConnection method
Channel: channelName given by Source via AddChannel method
Chan0Data Sinks request channels (AddChannel) using either relative or absolute (full-path) names. For example:
Test43/C0
Test43/C1
A/B/C
/Server/MySource/Test43/C2 # absolute pathAbsolute paths start with a slash, and include the top level (parent) server all the way down to the channel name(s). Relative paths do not start with a slash, and begin with the Source name(s) on the local server.
MySource/Test43/C2 # relative path
For Sinks, and when requesting a list of available Server channels, wildcards can also be used, as in:
MySource/Test*/...Note: As of the current release, the default Server name is "Server".
The following Table summarizes the wildcard syntax available to the
AddChannel
(Sink-only) and GetChannelList (Sink or Source) methods.
| Match String | Description |
| "*" | All channels at this level (one deep) |
| "..." | All channels this level and down (recursive depth). Must be last part of multi-tiered name. |
| more to come |
Note: As of the current release, wildcards are not very well supported. The only supported use is the "..." notation used with the GetChannelList method.
The archiveMode parameter has one of the following values:
"none" - No archive is to be
used (default)
"load" - Load the archive that
matches this application clientName
"create" - Create a new archive, delete
an existing one if one is present
"append" - Add to an existing archive,
create a new one if necessary
For a Source client, these parameters have an obvious meaning and relate to the size and type of storage to be used for incoming source data.
By default, Sink clients have a single cache frame for storing its current data request. Note that even for Sinks, data requests are RMaps, and that multiple requests can be stored in sequence. This advanced sink request-buffer forms the foundation for future optimizations and the development of "Virtual RMaps".
Clients optionally provide a userName and password as part of the connection process. If these are defaulted to NULL, there will be no user name by which you can be granted access to restricted data.
Note: As of the current release, userName and password authorization is not implemented.
Note: The channel list may include channels from Sources other than the local application. I.e. this list can include more channels than those locally specified via the AddChannel method.
Memory allocation note for C/C++ programmers:
The data buffers returned by ChannelName and GetChannelList
are automatically allocated by the API, but are then "owned" and should
be released by the client application. A special C/C++ utility function,
rbnbFreeChannelList(clist,
nchan) is provided for this purpose.
| Data Type Code | Description |
| TYPE_FLOAT32 | Single precision (32 bit) floating point number |
| TYPE_FLOAT64 | Double precision (64 bit) floating point number |
| TYPE_INT8 | 8-bit integer (byte) |
| TYPE_INT16 | 16-bit integer (short int) |
| TYPE_INT32 | 32-bit integer (int) |
| TYPE_INT64 | 64-bit integer (long) |
| TYPE_STRING | Variable length String (character array) object |
| TYPE_UNKNOWN | Unknown or unspecified (byte array) |
When specifying a primitive Data Type with a word length greater than 8 bits (1 byte), the word order (MSB,LSB) is automatically set to match that of the local native CPU upon which the Source application runs.
Define a channel list Set TimeStamp(s) Specify data for channel(s) Flush data to RBNB server
Each manual timestamp applies to the data specified by one or more subsequent calls to PutChannel, until a time-setting method is called again. Thus, you can choose to timestamp data point by point, channel by channel, or frame by frame depending on how you interleave your calls to SetTime and PutChannel.
RBNB timestamps must monotonically increase. Thus, if you are manually providing timestamps, be sure to always increase the value of the start time with each subsequent call to SetTime.
"next" - increment
timestamp by one (1) each time
"timeofday" - set timestamp to system time-of-day
at the point of each transmittal
Automatic time stamps are updated once upon each data Flush. Thus, automatic timestamps are always frame by frame. Use the SetTime method to timestamp data channel by channel or point by point.
PutChannel may be called multiple times per channel per Flush, building up a many-point-per-channel data frame in a piecemeal manner as may be convenient to the application. The SAPI has sophisticated "Deep CVT" logic which automatically consolidates and organizes data into efficient RMap structures. It will always be somewhat more efficient to handle fewer, larger data buffers, however.
Memory allocation note for C/C++ programmers:
The data buffers provided by a source to the API are "owned" by the
client application. I.e. the client application is responsible to
allocate and free its own data buffers.
Note: Mixing different Data Types in a single channel is not supported, and may cause difficulties for Sink applications that try to extract mixed-type data.
Note: PutChannelAsString puts a single String object, which is considered to be an indivisible data word.
Each call to Flush involves round-trip network communication, therefore staging larger data frames (with larger buffers and/or multiple calls to PutChannel) prior to flushing them may provide a significant performance advantage. Of course, you need to also consider the associated impact on memory use and latency when deciding how often to Flush your data.
If the blockingIO parameter is true, it will block until the data is sent. If there is no data to send, calling Flush(true) will synchronize your application with the server. It returns the number of channels sent.
Note: Only channels with new data (via PutChannel) since the previous call to Flush are actually sent, not necessarily the entire Channel List.
|
Source mySource = new Source(); mySource.OpenRBNBConnection("localhost", "mySource"); int index = mySource.AddChannel("myChan"); mySource.AutoTimeStamp("timeofday"); mySource.PutChannelAsString(index, "Hello World!"); mySource.Flush(true); . |
Specify a channel list to request Select a sink mode Fetch data from RBNB server Extract data and time from API buffer(s)
Subscribe is the most efficient mode in that data frames are streamed from the server without waiting for acknowledgment from the sink client. If the client does not keep up, the data delivered will fall further and further behind until it falls off the beginning (oldest) data in the source ring buffer, at which point the stream aborts.
When Monitor mode keeps up, it is much like Subscribe, except that there is more round-trip traffic between the client and server for Monitor mode (to establish the gapControl criterion). Unlike Subscribe mode, the stream will not abort if the client doesn't keep up; but data can be dropped with resulting gaps.
When dealing with a timeRef of newest, there are some special notes:
Normally (with the default fetchByFrame=false ), a single Request results in a single consolidated Fetch response. Set fetchByFrame=true to cause the data returned by Fetch to be on a source frame-by-frame basis. This means the size of the data per Fetch matches the frame-size set by the respective Source. Thus, a single Request can require multiple calls to Fetch. Requesting data by frame may be more efficient or convenient, for example with indivisible video frames.
If the blockingIO parameter is true, it will block until the data is retrieved. Otherwise, it will either return a positive integer indicating data was ready and has been read, or a zero (0) indicating no data was yet available.
The ChannelData and ChannelTime methods return the
data associated with the given channel. Channels are denoted by chanIndex,
which always runs from 0 to (N-1), where N is
the return value of Fetch. The
channel name can be determined from the channel index via the channelName
method. Or, knowing the name, the chanIndex can be derived from the
channel name via the ChannelIndex
method.
Memory allocation note for C/C++ programmers:
The data buffers for the fetched data are automatically allocated by
the API, but are then "owned" by the client application. I.e. the
client application is responsible to free the extracted data and time buffers,
using the standard system free() function.
Note: ChannelDataAsString gets an array of String objects, where each String is considered to be an indivisible, individually time-stamped, variable-length data word.
If necessary, the point times will be linearly interpolated from the underlying start time and duration of the corresponding data array. See SetTime.
|
Sink mySink = new Sink(); mySink.OpenRBNBConnection("localhost", "mySink"); mySink.AddChannel("mySource/myChan"); mySink.Request(0., 1., "oldest"); mySink.Fetch(true); System.out.println( mySink.ChannelName(0) ": " + mySink.ChannelDataAsString(0)[0] ); . |