CAUTION! The Java NML Interface was changed since this document was written. Although the interface described here is still avialable and the examples are written in java. Java programmers should probably see NML Programmers Interface (Java Version).
When using languages other than C++ with NML, there are several problems. The header files with the NML message definitions can not be included. The libraries for managing the NML communications are not available. In the case of a Java applet the NML configuration file might also not be available. One solution to this problem is to link together C++ code with the code written in another language into a single program. This was the approach used in the EMC Graphical User Interface which is primarily written in Visual Basic. Another approach is that the program written in non-C++ connect via sockets to an NML server. However because the NML server has many options writing the client might require a great deal of work to support all the options. Also, the default interface requires handling binary data which can more difficult to deal with than text, especially in scripting languages. Here I will choose a set of options that simplifies the interface for a Java client and describe how the client can be written.
On each buffer line for buffers remove any of the following if they were there: (TCP=?, UDP=?, ascii, xdr). Then add "STCP=" to set the remote protocol to a simplified TC P protocol to the end of each buffer line. Unlike the normal TCP protocol, each buffer must have a unique port. Add "disp" to set the updater type to the ascii display type.
To open a connection create a new socket, making sure to match the host and port from the NML configuration file.String host = "giskard.cme.nist.gov"; int port = 2001; Socket nmlsocket; nmlSocket = new Socket(host, port);
Then create a DataInputStream and DataOutputStream using that socket.DataOutputStream nmlOs; DataInputStream nmlIs; nmlOs = new DataOutputStream(nmlSocket.GetOutputStream); nmlIs = new DataInputStream(nmlSocket.GetInputStream);
To read from an NML buffer, write "read:\n" or "peek:" to the DataOutputStream, then read a line from the DataInputStream. The line will contain the NML message beginning with the type and size of the message and followed by members in the order the update functions are called. (The size indicates the size of the structure in C++ not the length of the string returned. -- Ignore it.) The parameters are separated by commas. Below is an example of how to parse this string.// Receive the current position. String nmlMsgString; long type; long size; float x; int index; nmlOs.writeBytes("read:\n"); nmlMsgString = nmlIs.ReadLine(); // nmlMsgString might look like this "8010,32,5.0,-25.0,0.7" type = (Long.valueOf(nmlMsgString)).longValue(); index = nmlMsgString.indexOf(","); size = (Long.valueOf(nmlMsgString.substring(index))).longValue(); index = nmlMsgString.indexOf(",",index); x = (Float.valueOf(nmlMsgString.substring(index))).floatValue(); To write to a NML buffer send write "write:" or "write_if_read:" followed by the message in the same form as they are read in, beginning with the type and size followed by members separated by commas. It is not necessary to provide all of the members of the message. Members omitted from the end of the string will be considered to be zero. It is also not necessary to calculate the size of the message, but a place holder is necessary if there are any other members to set in the string. // Send the command to goto x,0,0 nmlOs.writeBytes("8001,0," + (new Double(x)).toString());
This example consists of 3 programs:
The applet looks somewhat like a stopwatch. The controller doesn't have any hardware to control so I simulate world model by just updating the time in the world model buffer. Since we lack the computing resources here to run a separate controller for each user that starts the applet, pressing reset, start, or stop changes not only your display but also the display of anyone else viewing this applet.
NOTE:This applet that used to be here no longer works from this web page and has not worked for some time because of some security settings placed on this web server by our IT department.
Last Modified: 03/25/97
If you have questions or comments regarding this page or you would like to be notified of changes to the RCS library via email, please contact Will Shackleford at shackle [at] cme.nist.gov (shackle@c)