%D% Java Inteface to NML

Connecting to NML from languages (such as Java) other than C++ via sockets.


Introduction

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. Here I will choose a set of options that simplifies the interface for a Java client and describe how the client can be written.

NML Configuration

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 TCP 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.

Java Socket Code

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 seperated by commas. Below is an example of how to parse this string.

	// Recieve 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);
	index = nmlMsgString.indexOf(",");
	size = Long.valueOf(nmlMsgString.substring(index));
	index = nmlMsgString.indexOf(",",index);
	x = Float.valueOf(nmlMsgString.substring(index));
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, begining with the type and size followed by members seperated by commas. It is not neccessary to provide all of the members of the message. Members ommitted from the end of the string will be considered to be zero. It is also not neccessary to calculate the size of the message, but a place holder is neccessary if there are any other members to set in the string.
	// Send the command to goto x,0,0
	nmlOs.writeBytes("8001,0," + Double(x).toString());

A Complete Example

This example consists of 3 programs:

  1. A C++ pseudo controller which accepts commands and updates a world model buffer. (wtimer.cc,timetype.cc, and timetype.hh)
  2. A C++ server which passes messages back and forth between remote processes and the local buffers read and updated by the controller.(timesvr.cc,timetype.cc, and timetype.hh)
  3. A Java Applet that sends commands when buttons are pushed and polls the world model for display. (socapplet.java and CountButton.java)

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 veiwing this applet.

View the Applet

Last Modified: %H%

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@cme.nist.gov